/*
 * formBase.java
 *
 * Created on 9 aprile 2008, 11.10
 */

package our.gui;

import java.awt.Cursor;
import java.awt.Frame;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.Timer;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.ToolTipManager;
import javax.swing.border.SoftBevelBorder;

/**
 *
 * @author  keysman
 */
public abstract class ourForm extends javax.swing.JDialog implements ourInterfaceForm {

    //private int XSTART;
    //private int YSTART;
    //private int WIN_WIDTH;
    //private int WIN_HEIGHT;
    
    // Definisco le modalità in cui si può trovare l'utente
    public final static int MODE_VIS = 0;
    public final static int MODE_INS = 1;
    public final static int MODE_MOD = 2;
        
    private int USER_MODE = MODE_VIS; // La modalità in cui strova l'utente
    
    private Timer timer = null; // Il timer
    
    public static SoftBevelBorder BUT_BORDER_EXITING = null;
    
    private List W_LSTTEXTFIELDS = null; // In queste due liste venogno memorizzati i valori dei campi per la verifica 
    private List W_LSTTABLES     = null; // in fase di uscita

    private boolean _ISKEYFRAMEENABLED = true; // flag che indica se siamo nel keyframe o meno

    private String _KEYFLDSVALS = ""; // La stringa separata da § composta dai valori contenuti nei campi chiave

    private boolean _ISZOOMONZOOM = false; // Flag che indica che la form è stata chiamata da un F4

    protected Object[][] form_db_binding = null; // Oggetto per la mappatura form/db

    private Object[] _KEYFIELDS = null; // Array contenente gli 'oggetti' del keyframe

    private ArrayList<ourButton> _ZOOMON_BUTTONS; // Array contenente i pulsanti creatia a runtime di tipo ZoomOn

    private String _DB_Table = ""; // Nome della tabella alla quale la form è associata

    //private String _DB_Sort_Fields = ""; // Elenco dei campi su cui viene effettuato l'orindamento dei record

    private String _DB_txtId_Field = ""; // Il campo del db che andrà posizionato in txtID

    private boolean _bREALDELETE = false; // Se cancellare fisicamente il record

    private Object[] _HM_GOTO = null;

    private String _PRINTFORMNAME = ""; // Il nome della class adibita alla stampa

    /*public String getDB_Sort_Fields() {
        return _DB_Sort_Fields;
    }

    public void setDB_Sort_Fields(String _DB_Sort_Fields) {
        this._DB_Sort_Fields = _DB_Sort_Fields;
    }*/

    public String getDB_txtId_Field() {
        return _DB_txtId_Field;
    }

    public void setDB_txtId_Field(String _DB_txtId_Field) {
        this._DB_txtId_Field = _DB_txtId_Field;
    }
    public String getDB_Table() {
        return _DB_Table;
    }

    public void setDB_Table(String _DB_Table) {
        this._DB_Table = _DB_Table;
    }

    protected void addZoomOnButton(ourButton but)
    {
        _ZOOMON_BUTTONS.add(but);
    }

    protected String _STRTITLE = "";
    //protected int _WIDTH = 10;
    //protected int _HEIGHT = 10;
    protected java.awt.Frame _PARENT = (Frame) getParent();
    protected boolean _MODAL = true;

    /** Creates new form formBase */
    //public ourForm(String strTitle, int XSTART, int YSTART, int W, int H, java.awt.Frame parent, boolean modal)
    public ourForm(/*String strTitle, int W, int H, */java.awt.Frame parent, boolean modal)
    {
        //super(parent, modal);
        super(parent, modal);
        initComponents();
        _ZOOMON_BUTTONS = new ArrayList<ourButton>();
        setDefaultCloseOperation(javax.swing.JFrame.DO_NOTHING_ON_CLOSE);
        setResizable(false);
        //setTitle(strTitle);
        txtID.setVisible(false); // Nascondo il campo ID
        //this.XSTART = XSTART;
        //this.YSTART = YSTART;
        //this.WIN_HEIGHT = H;
        //this.WIN_WIDTH = W;
        // Posiziono il dialogo al centro dello schermo
        java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
        java.awt.Dimension screenSize = tk.getScreenSize();
        int iScrH = screenSize.height;
        int iScrW = screenSize.width;

        // Carico i parametri per il dimensionamento della finestra
        String strFormName = "";
        if(getClass().getName().lastIndexOf(".")>=0)
            strFormName = getClass().getName().substring(getClass().getName().lastIndexOf(".") + 1);
        else
            strFormName = getClass().getName();

        System.out.println(strFormName);
        String strTop = our.gui.utils.getConfigXMLParams(strFormName + ".top");
        String strLeft = our.gui.utils.getConfigXMLParams(strFormName + ".left");
        String strHeight = our.gui.utils.getConfigXMLParams(strFormName + ".height");
        if(strHeight==null || strHeight.length()==0)
        {
            our.gui.utils.logger.log(Level.SEVERE, strFormName + ": altezza non definita!");
            System.exit(1);
        }
        String strWidth = our.gui.utils.getConfigXMLParams(strFormName + ".width");
        if(strWidth==null || strWidth.length()==0)
        {
            our.gui.utils.logger.log(Level.SEVERE, strFormName + ": larghezza non definita!");
            System.exit(1);
        }

        int iHeight = Integer.parseInt(strHeight); // Altezza della finestra
        int iWidth = Integer.parseInt(strWidth);  // Larghezza della finestra

        int iTop = 0;
        if(strTop!=null && strTop.length()>0)
            iTop = Integer.parseInt(strTop);
        else
            iTop = (iScrH - iHeight) / 2;

        int iLeft = 0;
        if(strLeft!=null && strLeft.length()>0)
            iLeft = Integer.parseInt(strLeft);
        else
            iLeft = (iScrW - iWidth) / 2;

        setBounds( iLeft,
                   iTop,
                   iWidth,
                   iHeight);

        setTitle(our.gui.utils.getConfigXMLParams(strFormName + ".caption"));
        panelToolbar.setSize(iWidth - 7, 36);
        panelStatus.setBounds(2, iHeight-54, 50, 19);
        panelInfo.setBounds(56, iHeight-54, iWidth-135, 19);
        panelOther.setBounds(iWidth-75, iHeight-54, 65, 19);
        setPreferredSize(new java.awt.Dimension(iWidth, iHeight)); // Ridimensiono la finestra

        // Personalizzo il gestore degli eventi
        CustomEvent customEvent = new CustomEvent();
        Action f1    = new FXAction("F1", customEvent);
        Action f2    = new FXAction("F2", customEvent); // Zoom
        Action f3    = new FXAction("F3", customEvent); // Modifica il record
        Action f4    = new FXAction("F4", customEvent); // Zoom on Zoom
        Action f5    = new FXAction("F5", customEvent); 
        Action f6    = new FXAction("F6", customEvent); // Vai precedente
        Action f7    = new FXAction("F7", customEvent); // Vai successivo
        Action f8    = new FXAction("F8", customEvent); // Cancella record corrente
        Action f9    = new FXAction("F9", customEvent); // Salva i dati
        Action shf5  = new FXAction("SHF5", customEvent); // Vai al primo
        Action shf7  = new FXAction("SHF7", customEvent); // Vai all'ultimo
        Action esc   = new FXAction("ESC", customEvent);   // Chiudi la maschera
        Action up    = new FXAction("UP", customEvent);    // Sposta il fuoco sull'oggetto precedente
        Action down  = new FXAction("DOWN", customEvent); // Sposta il fuoco sull'oggetto successivo
        
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0, false), "F1");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0, false), "F2");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0, false), "F3");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0, false), "F4");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0, false), "F5");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0, false), "F6");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0, false), "F7");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0, false), "F8");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0, false), "F9");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, InputEvent.SHIFT_DOWN_MASK, false), "SHF5");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F7, InputEvent.SHIFT_DOWN_MASK, false), "SHF7");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "ESC");
        
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DOWN");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0, false), "DOWN");// "TAB");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "DOWN"); //ENTER");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK, false), "UP");//SHTAB");
        
        getRootPane().getActionMap().put("F1", f1);
        getRootPane().getActionMap().put("F2", f2);
        getRootPane().getActionMap().put("F3", f3);
        getRootPane().getActionMap().put("F4", f4);
        getRootPane().getActionMap().put("F5", f5);
        getRootPane().getActionMap().put("F6", f6);
        getRootPane().getActionMap().put("F7", f7);
        getRootPane().getActionMap().put("F8", f8);
        getRootPane().getActionMap().put("F9", f9);
        getRootPane().getActionMap().put("SHF5", shf5);
        getRootPane().getActionMap().put("SHF7", shf7);
        getRootPane().getActionMap().put("ESC", esc);
        
        getRootPane().getActionMap().put("UP", up);
        getRootPane().getActionMap().put("DOWN", down);

        // Riposiziona i pulsanti a seconda della dimensione della finestra
        butInfo.setBounds(iWidth-43, 5, 26, 26);
        butPrnscr.setBounds(iWidth-71, 5, 26, 26);
        butStampa.setBounds(iWidth-99, 5, 26, 26);
        butCalc.setBounds(iWidth-127, 5, 26, 26);
        jButton3.setBounds(iWidth-155, 5, 26, 26);
        int iGap = (int) ((iWidth - 443) / 3); // Lnghezza di un gap tra i blocchi centrali
        
        // Posiziono i cursori
        butFirst.setBounds(64 + iGap, 5, 26, 26);
        butPrev.setBounds(92 + iGap, 5, 26, 26);
        butNext.setBounds(120 + iGap, 5, 26, 26);
        butLast.setBounds(148 + iGap, 5, 26, 26);
        
        // Riposiziono il blocco dei tasti azione record
        butEdit.setBounds(176 + iGap * 2, 5, 26, 26);
        butZoom.setBounds(204 + iGap * 2, 5, 26, 26);
        butAzienda.setBounds(232 + iGap * 2, 5, 26, 26);
        butElimina.setBounds(260 + iGap * 2, 5, 26, 26);
        
        // Definisco il bordo dei pulsanti
        BUT_BORDER_EXITING = new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED);

        // Mostra i tooltip immediatamente
        ToolTipManager.sharedInstance().setInitialDelay(0);
    }

    protected void setPrintForm(String strPrintForm)
    {
        if( (strPrintForm==null) || (strPrintForm.length()==0) ) return;
        _PRINTFORMNAME = strPrintForm;
        try {
            Class.forName(_PRINTFORMNAME);
            // Se esiste la corrispondente classe per la gestione delle stampa, attivo il pulsante di stampa
            butStampa.setEnabled(true);
        } catch(java.lang.ClassNotFoundException cnfe) {
            our.gui.utils.logger.log(Level.SEVERE, cnfe.toString());
        }
    }

    /**
     * Funzione chiamata unicamente dagli oggetti contenuti nella form
     * @param _obj Oggetto chiamante
     */
    /*public void objectHasLostFocus(Object _obj) {
        if(_FORCEAVOIDFOCUSMANAGE) return;
        if( !(_obj instanceof ourTextField) &&
            !(_obj instanceof javax.swing.JTextField) ) return; // Se non è un istanza di ourTextField, ritorno
        if(!_MANAGEFOCUS) return;

        if(_FOCUS_LOSER!=null)
        {
            _FOCUS_LOSER=null;
            return;
        }

        _FOCUS_LOSER = _obj;

        _MANAGEFOCUS = false;
        ourTextField myTxt = (ourTextField)_obj;
        if(!(myTxt.ISVALID(true))) {
            if(myTxt.SETTINGS.emptyIfNotExist()) myTxt.reset();
            myTxt.requestFocus();
        } else {
            _FOCUS_LOSER = null;
        }
        _MANAGEFOCUS = true;
        
    }*/

    /**
     * Imposta il flag per indicare che la form corrente è stata chiamata da un F4
     * @param bIsZoZ true se è stata chiamata da un F4 false altrimenti
     */
    public void isZoomOnZoom(boolean bIsZoZ)
    {
        _ISZOOMONZOOM = bIsZoZ;
        butSalva.setEnabled(true);
    }
    
    /**
     * Blocca il record visualizzata dall'utente: se nel frattempo è stato bloccato
     * da qualcun altro lo segnala.
     * @param isInsertionMode true se siamo in inserimento, false altrimenti
     * @return true se il lock è riuscito, false altrimenti
     */
    public boolean setLock(boolean isInsertionMode)
    {
        boolean bRet = true;
        try {
            //our.gui.dbase.models.Locks tmpLock = new our.gui.dbase.models.Locks();
            //tmpLock.setForm(getTitle()); // Titolo del form
            String strForm = getTitle();
            String strIdRecord = "";
            if(!txtID.getText().isEmpty())
                strIdRecord = txtID.getText(); // ID del record
                //tmpLock.setIdRecord(Integer.parseInt(txtID.getText()));
            else
                strIdRecord = "0"; // 0 se sono in inserimento
                //tmpLock.setIdRecord(0);
            String strIsInsertMode = isInsertionMode ? "1" : "0"; // Indica se il lock è su un record in 'inserimento'
            //tmpLock.setIsInsertMode(isInsertionMode);
            String strUserDefined = isInsertionMode ? USER_FOUND_KEY() : null;
            //if(isInsertionMode) strUserDefined = USER_FOUND_KEY();
            String strKeyvals = "";
            if( (isInsertionMode) && (strUserDefined!=null) ) // Se entro in inserimento chiamo la funzione USER_FOUND_KEY
                strKeyvals = strUserDefined; // La stringa keys customizzata
                //tmpLock.setKeyvals(strUserDefined); // La stringa keys customizzata
            else
                strKeyvals = getKeyValsString(false); // La stringa keys
                //tmpLock.setKeyvals(getKeyValsString(false)); // La stringa keys
            String strUsern = our.gui.utils.DBUSER;  // Utente
            //tmpLock.setUsern(our.gui.utils.DBUSER); // Utente
            String strTimest = new java.util.Date().toString();
            //tmpLock.setTimest(new java.util.Date());

            Statement stmt = our.gui.utils.connection.createStatement();
            String strQuery = "INSERT INTO LOCKS(FORM, USERN, KEYVALS, ID_RECORD, IS_INSERT_MODE) VALUES (";
            strQuery += "'" + strForm + "', ";
            strQuery += "'" + strUsern + "', ";
            strQuery += "'" + strKeyvals + "', ";
            strQuery += "'" + strIdRecord + "', ";
            strQuery += "'" + strIsInsertMode + "')";
            stmt.executeUpdate(strQuery);
            stmt.close();
            //our.gui.utils.sqlMap.insert("LOCKS.abatorgenerated_insert", tmpLock);
        } catch(SQLException ex) {
            // Se sono in modalità inserimento ma un altro utente mi ha anticipato
            // nella richesta del lock sullo stesso record, riporto lo stato in visualizzazione
            if(USER_MODE==MODE_INS && isInsertionMode==true)
            {
                if(checkLock())
                {
                    setUserMode(MODE_VIS);
                    butEdit.setEnabled(false);
                    our.gui.utils.MessageBox("Il record richiesto è in fase di inserimento!", JOptionPane.INFORMATION_MESSAGE);
                }
            } else {
                our.gui.utils.MessageBox("Un altro utente ha acquisito i privilegi sul record!", JOptionPane.INFORMATION_MESSAGE);
            }
            bRet = false;
        } finally {
            if(bRet && USER_MODE==MODE_MOD) startTimer(); // In inserimento non imposto il timer
            return bRet;
        }
    }
    
    /**
     * Rimuove il lock impostato
     */
    public void removeLock()
    {
        //our.gui.dbase.models.Locks lockTmp = new our.gui.dbase.models.Locks();
        
        //lockTmp.setForm(getTitle());
        String strTitle = getTitle();
        String strKeyvals = getKeyValsString(false);
        //lockTmp.setKeyvals(getKeyValsString(false));
        try {
            Statement stmt = our.gui.utils.connection.createStatement();
            String strQuery = "DELETE FROM LOCKS WHERE ";
            strQuery += "FORM='" + strTitle + "' AND ";
            strQuery += "KEYVALS='" + strKeyvals + "'";
            stmt.executeUpdate(strQuery);
            stmt.close();
            //our.gui.utils.sqlMap.delete("LOCKS.abatorgenerated_deleteByPrimaryKey", lockTmp);
        } catch(SQLException sqle) {
            our.gui.utils.logger.log(Level.SEVERE, sqle.toString());
        } finally {
            stopTimer();
        }
    }
        
    /**
     * Questa funzione è accessibile da tutti e permette di impostare il messaggio
     * di help della status bar.
     * @param str Il messaggio da visualizzare
     */
    static public void updateStatusHelp(String str)
    {
        panelInfo.setText(str);
    }
    
    /**
     * Imposta la forma del cursore
     * @param CURSOR
     */
    public void setCustomCursor(int CURSOR)
    {
        Cursor normalCursor = new Cursor(CURSOR);
        setCursor(normalCursor);
    }
    
    /**
     * Questa funzione DEVE essere chiamata ogni volta che un utente lokka
     * il record.
     */
    public void startTimer()
    {
        ActionListener actionTimer = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                //UNLOCK();
                removeLock();
                our.gui.utils.MessageBox("Hai perso i privilegi di scrittura/modifica del record.", JOptionPane.WARNING_MESSAGE);
            }
        };
        timer = new Timer((int)our.gui.utils.LOCK_TIMEOUT, actionTimer);
        timer.start(); 
    }
    
    /**
     * Arresta il timer
     */
    public void stopTimer()
    {
        if(timer!=null)
        {
            timer.stop();
            timer = null;
        }
    }
    
    /**
     * Ripristina la form nella condizione iniziale: svuota i campi
     */
    private void reset()
    {
        // Imposto la modalità in Visualizazione
        setUserMode(MODE_VIS);
        // Svuoto i campi
        resetFields(true);
    }
    
    /**
     * 
     * @param NEW_MODE Modalità da impostare: MODE_VIS, MODE_INS, MODE_MOD.
     * @return true se il cambio è avvenuto, false altrimenti
     */
    public boolean setUserMode(int NEW_MODE)
    {
        USER_MODE = NEW_MODE;
        switch(NEW_MODE)
        {
            case MODE_VIS:
                setStatusText(" VIS");
                //butAzienda.setEnabled(true);
                butEdit.setEnabled(true);
                butElimina.setEnabled(true);
                butFirst.setEnabled(true);
                butPrev.setEnabled(true);
                butNext.setEnabled(true);
                butLast.setEnabled(true);
                butInfo.setEnabled(true);
                butPrnscr.setEnabled(true);
                butStampa.setEnabled(true);
                butZoom.setEnabled(true);
                butSalva.setEnabled(false);
                break;
            case MODE_INS:
                // Se l'utente non è abilitato all'inserimento di un nuovo record lo segnalo
                if(our.gui.utils.USER_ALLOW_INS==false)
                {
                    our.gui.utils.MessageBox("Utente non abilitato all'operazione richiesta!", JOptionPane.WARNING_MESSAGE);
                    USER_MODE = MODE_VIS;
                    return false;
                }
                if(!this.setLock(true)) return false;
                resetFields(false);
                butAzienda.setEnabled(false);
                butEdit.setEnabled(false);
                butElimina.setEnabled(false);
                butFirst.setEnabled(false);
                butPrev.setEnabled(false);
                butNext.setEnabled(false);
                butLast.setEnabled(false);
                butInfo.setEnabled(false);
                butPrnscr.setEnabled(false);
                butStampa.setEnabled(false);
                butZoom.setEnabled(false);
                butSalva.setEnabled(true);
                setStatusText(" INS");
                txtID.setText("");
                enableFields(true);
                updateWorking();
                break;
            case MODE_MOD:
                setStatusText(" MOD");
                butAzienda.setEnabled(false);
                butEdit.setEnabled(false);
                butSalva.setEnabled(true);
                butElimina.setEnabled(false);
                butFirst.setEnabled(false);
                butPrev.setEnabled(false);
                butNext.setEnabled(false);
                butLast.setEnabled(false);
                butInfo.setEnabled(false);
                butPrnscr.setEnabled(false);
                butStampa.setEnabled(false);
                butZoom.setEnabled(false);
                break;
        }
        if(_ISZOOMONZOOM)
            butSalva.setEnabled(true);

        return true;
    }
    
    public int getUserMode()
    {
        return USER_MODE;
    }
    
    /**
     * Imposto il testo nella statusbar
     * @param strTxt Nuovo testo
     */
    public void setStatusText(String strTxt)
    {
        panelStatus.setText(strTxt);
    }


    /**
     * Verifica se abilitare o meno i pulsanti di edit e/o delete
     * quando si naviagano i record.
     */
    private void checkIfEnableEditAndDelButtons()
    {
        if(checkLock()==true)
        {
            butEdit.setEnabled(false);
            butElimina.setEnabled(false);
        } else {
            butEdit.setEnabled(true);
            butElimina.setEnabled(true);
        }
    }
    
    
    // Inner class
    class FXAction extends AbstractAction {
        private String key;
        private CustomEvent customEvent;
        
        public FXAction(String key, CustomEvent customEvent)
        {
            this.key = key;
            this.customEvent = customEvent;
        }

        public void actionPerformed(ActionEvent e) {
            if(customEvent!=null)
            {
                customEvent.esegui(key);
            }
        }
    }
    
    /**
     * Cicla su ogni elemento della maschera per cercare gli elementi che appartengono
     * alla chiave. In caso positivo aggiunge alla stringa di ritorno il valore: nome_campo=valore_contenuto
     * @return La clausola where composta dalle coppio chiave=valore
     */
    private String getGotoString()
    {
        String strRet = "";
        // Ciclo in _KEYFIELDS per leggere il contenuto dei campi in chiave
        for(int i=0; i<_KEYFIELDS.length; i++)
        {
            if(_KEYFIELDS[i].getClass().toString().indexOf("ourTextField")>=0)
            {
                ourTextField txtTmp = (ourTextField)_KEYFIELDS[i];
                strRet = txtTmp.getFieldOnDB() +  "='" + txtTmp.getText() + "' AND ";
            }
        }
        strRet = strRet.substring(0, strRet.length() - 5);
        return strRet;
        
    }


    
    // Inner class
    class CustomEvent {
        public void esegui(String key)
        {
            if( key.equalsIgnoreCase("SHF5") ) 
            {
                butLastMouseClicked(null);
            }
            if( key.equalsIgnoreCase("SHF7") ) 
            {
                butFirstMouseClicked(null);
            }
            if( key.equalsIgnoreCase("F2") )
            {
                 butZoomMouseClicked(null);
            }
            if( key.equalsIgnoreCase("F3") )
            {
                butEditMouseClicked(null);
            }
            if( key.equalsIgnoreCase("F4") )
            {
                try {
                    our.gui.ourTextField ourTxt = (ourTextField)findComponentWithFocus();
                    //if(!ourTxt.SETTINGS.isZoomOnZoom()) return;
                    if(!ourTxt.isIsZoomOnZoomEnabled()) return;
                } catch(java.lang.ClassCastException cce) { }
                // Simulo la pressione del tasto sinistro del mouse sul textfiels txtID per identificare l'evento F4
                java.awt.event.MouseEvent evtF4 = new java.awt.event.MouseEvent(txtID,java.awt.event.MouseEvent.MOUSE_PRESSED,0,0,0,0,0,false);
                butZoomMouseClicked(evtF4);
            }
            if( key.equalsIgnoreCase("F5") ) 
            {
                butNextMouseClicked(null);
            }
            if( key.equalsIgnoreCase("F6") )
            {
                butStampaMouseClicked(null);
            }
            if( key.equalsIgnoreCase("F7") ) 
            {
                butPrevMouseClicked(null);
            }
            if( key.equalsIgnoreCase("F8") ) 
            {
                butEliminaMouseClicked(null);
            }
            
            if( key.equalsIgnoreCase("F9") ) 
            {
                butSalvaMouseClicked(null);
            }

            if(key.equalsIgnoreCase("ESC")) 
            {
                butEsciMouseClicked(null);
                // Se non c'è la form si stampa disabilito il pulsante
                try {
                    String strClsStampa = "stampe.formStampe" + getClass().getName().substring(14);
                    Class clsStampa = Class.forName(strClsStampa);
                    // Se esiste la corrispondente classe per la gestione delle stampa, attivo il pulsante di stampa
                    butStampa.setEnabled(true);
                } catch(java.lang.ClassNotFoundException cnfe) {
                    // La classe non c'è... quindi disabilito il pulsante
                    butStampa.setEnabled(false);
                }
            }
            
            if(key.equalsIgnoreCase("DOWN"))
            {
                KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
                boolean bIsLastElement = ( _ISKEYFRAMEENABLED && isLastElement() );
                if( bIsLastElement )
                {
                    String strCurKeyFldsVals = getKeyValsString(true); // Leggo i valori contenuti nei campi in chiave
                    if((!strCurKeyFldsVals.equals(_KEYFLDSVALS)) && (strCurKeyFldsVals.indexOf("##")<0) )
                    {
                        System.out.println("***********************************************");
                        System.out.println("* In questo punto devo implementare il GOTO() *");
                        if(!readRecord(getGotoString()))
                        {
                            // Il record non esiste... entro in inserimento
                            setUserMode(MODE_INS);
                        }
                        GOTO();
                        System.out.println("***********************************************");
                        if(getUserMode()==MODE_VIS)
                        {
                            if(checkLock()==true)
                            {
                                butEdit.setEnabled(false);
                                butElimina.setEnabled(false);
                            } else {
                                butEdit.setEnabled(true);
                                butElimina.setEnabled(true);
                            }
                        }
                        _KEYFLDSVALS = strCurKeyFldsVals;
                    }
                    if(checkFieldWithFocus(true)) kfm.focusNextComponent();
                } else if(checkFieldWithFocus(true)==false) {
                    return;
                } else {
                    kfm.focusNextComponent();
                }
            }

            if(key.equalsIgnoreCase("UP"))
            {
                if(checkFieldWithFocus(true)==false) return;
                KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
                kfm.focusPreviousComponent();
            }

            if( (key.equalsIgnoreCase("F5")) || (key.equalsIgnoreCase("F7")) ||
                (key.equalsIgnoreCase("SHF5")) || (key.equalsIgnoreCase("SHF7")) )
            {
                javax.swing.JComponent cmp = findComponentWithFocus();
                if(cmp!=null)
                {
                    if(cmp.getClass().toString().indexOf("TextField")>=0)
                    {
                        ((javax.swing.JTextField)cmp).setSelectionStart(0);
                        ((javax.swing.JTextField)cmp).setSelectionEnd( ((javax.swing.JTextField)cmp).getText().length() );
                    }
                }
            }
        }
    }

    /**
     * Funzione chiamata da CALLZOOM (Zoom On Zoom) appartenente alle funzioni di zoom
     * @param hm
     */
    public void setUsersPKValues(Object[] objUsersPKVals)
    {
        _HM_GOTO = objUsersPKVals;
    }

    /**
     * Verifico se tra tutti gli elementi del keyframe, quello che possiede il fuoco è l'ultimo
     * @return true se l'elemento corrente è l'ultimo, false altrimenti
     */
    private boolean isLastElement()
    {
        boolean bRet = false;
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                // Lascio la prima condizione per retrocompatibilità con oggetti del tipo non our.gui puri.
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                    if( (obj!=null) && ((java.lang.Boolean)obj==true) ) {
                        if(field.getType().toString().indexOf("TextField")>=0)
                        {
                            our.gui.ourTextField txtTmp = (our.gui.ourTextField)field.get(this);
                            if(txtTmp.hasFocus() && txtTmp.SETTINGS.isLastElementInKeyFrame())
                            {
                                bRet = true;
                                break;
                            }
                        }
/************************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per la lettura del valore *
 ************************************************************************************************************************************/
                    }
                }
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return bRet;
    }

    /**
     * Setta il contenuto dei campi del keyframe
     * @param objVal Array di tipo Object[] contenente i valori da inserire nei campi del keyframe
     */
    protected void setKeyFieldVals(Object[] objVal)
    {
        for(int j=0; j<objVal.length; j++)
        {
            try {
                // Tramte reflection leggo tutti gli elementi appartenenti alla form
                java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
                // Ciclo tutti gl oggetti
                for(int i=0; i<flds.length; i++)
                {
                    // Identifico un singolo field
                    java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                    // Lo rendo accessibile
                    field.setAccessible(true);
                    // Lascio la prima condizione per retrocompatibilità con oggetti del tipo non our.gui puri.
                    if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                    {
                        Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                        if( (obj!=null) && ((java.lang.Boolean)obj==true) ) {
                            if(field.getType().toString().indexOf("TextField")>=0)
                            {
                                javax.swing.JTextField txtTmp = (javax.swing.JTextField)field.get(this);
                                if( ((String)objVal[j]).equalsIgnoreCase("-999") )
                                {
                                    txtTmp.setText("");
                                } else {
                                    txtTmp.setText((String)objVal[j]);
                                }
                            }
/************************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per la lettura del valore *
 ************************************************************************************************************************************/
                        }
                    }
                }
            } catch(Throwable t) {
                javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * Questa funzione viene chiamata dallo zoom o dalla gestione
     * @return Array contenente i valori contenuti nei campi del keyframe
     */
    public Object[] getKeyFieldVals()
    {
        return _KEYFLDSVALS.split("§");
    }

    /**
     * Controlla se TUTTI i campi del keyframe sono stati compilati
     * @return true se tutti i campi del keyframe contengono un valore, false altrimenti
     */
    private boolean allKeyFieldsFill()
    {
        boolean bRet = true;
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                // Lascio la prima condizione per retrocompatibilità con oggetti del tipo non our.gui puri.
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                    if( (obj!=null) && ((java.lang.Boolean)obj==true) ) {
                        if(field.getType().toString().indexOf("TextField")>=0)
                        {
                            javax.swing.JTextField txtTmp = (javax.swing.JTextField)field.get(this);
                            if(txtTmp.getText().isEmpty()) bRet = false;
                        }
/************************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per la lettura del valore *
 ************************************************************************************************************************************/
                    }
                }
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return bRet;
    }

    /**
     * Cerca l'oggetto nella form che possiede il fuoco. Chiama la funzione ISVALID e se il valore
     * ritornato non è true il fuoco non viene spostato.
     * @return
     */
    private boolean isValidField()
    {
        boolean bRet = true;
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                // Il primo controllo lo lascio per retro compatibilità con oggetti non our
                if( ( (field.getType().toString().indexOf("javax.swing")>=0) && ((field.getType().toString().indexOf("ButtonGroup")<0)) ) || 
                    (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    java.lang.reflect.Method method = javax.swing.JComponent.class.getMethod("hasFocus");
                    boolean bHasFocus = (java.lang.Boolean)method.invoke(field.get(this));
                    if(bHasFocus)
                    {
                         if(field.getType().toString().indexOf("TextField")>=0) {
                            our.gui.ourTextField txtTmp = (our.gui.ourTextField)field.get(this);
                            if(txtTmp.ISVALID(true)==false)
                            {
                                if(txtTmp.SETTINGS.emptyIfNotExist()) txtTmp.reset();
                                txtTmp.requestFocus();
                                bRet = false;
                                break;
                            }
                        }
                    }
                }
                field.setAccessible(false);
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return bRet;
    }
    
    /**
     * private Object getCommonObjectFunction(java.lang.reflect.Field[] fld, String strFunction)
     * 
     * Restituisce un Object come risultato alla chiamata alla funzione strFunction
     * che deve trovarsi nella classe commonObjectClass di un qualsiasi oggetto video customizzato
     * @param fld Il Field che contiene l'oggetto CommonObjectClass (this.getClass().getDeclaredField(flds[i].getName())
     * @param strFunction Il nome della funzione che si vuole chiamara
     * @return Un Object contenente il risultato
     */
    private Object getCommonObjectFunction(java.lang.reflect.Field field, String strFunction)
    {
        Object objRet = null;
        try {
            // Lo rendo accessibile
            field.setAccessible(true);
            //System.out.println(field.getName() + field.getType().toString());
            // Il primo controllo lo lascio per retro compatibilità
            if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
            {
                java.lang.reflect.Field[] fldSub = field.get(this).getClass().getDeclaredFields();
                for(int k=0; k<fldSub.length; k++)
                {                      
                    java.lang.reflect.Field mysub = field.get(this).getClass().getDeclaredField(fldSub[k].getName());
                    //System.out.println("                " + fldSub[k].getType().toString() + " -> " + fldSub[k].getName());
                    if(mysub.getType().toString().indexOf("commonObjectClass")>=0)
                    {
                        commonObjectClass tmp = null;
                        // Invoco la funzione per i TextArea
                        if(field.getType().toString().indexOf("TextArea")>=0)
                            tmp = ((ourTextArea)field.get(this)).SETTINGS;
                        // Invoco la funzione per i text field
                        if(field.getType().toString().indexOf("TextField")>=0)
                            tmp = ((ourTextField)field.get(this)).SETTINGS;
                        // Invoco la funzione per le label
                        if(field.getType().toString().indexOf("Label")>=0)
                            tmp = ((ourLabel)field.get(this)).SETTINGS;
                        // Invoco la funzione per le griglie
                        if(field.getType().toString().indexOf("Table")>=0)
                            tmp = ((ourTable)field.get(this)).SETTINGS;
                        // Invoco la funzione per i pulsanti
                        if(field.getType().toString().indexOf("RadioButton")>=0)
                        {
                            tmp = ((ourRadioButton)field.get(this)).SETTINGS;
                        } else {
                            if(field.getType().toString().indexOf("Button")>=0)
                                tmp = ((ourButton)field.get(this)).SETTINGS;
                        }
                        // Invoco la funzione per i check box
                        if(field.getType().toString().indexOf("CheckBox")>=0)
                            tmp = ((ourCheckBox)field.get(this)).SETTINGS;
/*********************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere la chiamata alle funzioni        *
 *********************************************************************************************************************************/ 
                        if(tmp!=null)
                        {
                            java.lang.reflect.Method method = tmp.getClass().getDeclaredMethod(strFunction);
                            objRet = method.invoke(tmp);
                        }
                     //System.out.println(fldSub[k].getName() + " : " + tmp.isExcludedFormAlter());
                     }
                }
            }
            field.setAccessible(false);
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            return objRet;
        }
    }
  
    /**
     * Aggiorna gli array che contengono le copie dei dati per effettuare il controllo
     * in fase di uscita
     */
    private void updateWorking()
    {
        W_LSTTABLES = new ArrayList();
        W_LSTTEXTFIELDS = new ArrayList();

        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                //System.out.println(field.getName() + field.getType().toString());
                // Il primo controllo lo lascio per retro compatibilità con oggetti non our
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    boolean bIsExludedFromAlter = true;
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isExcludedFormAlter");
                    if(obj!=null) 
                        bIsExludedFromAlter = (java.lang.Boolean)obj;
                    if(!bIsExludedFromAlter)
                    {
                        // Salvo i dati contenuti nei textArea
                        if(field.getType().toString().indexOf("TextArea")>=0)
                        {
                            java.lang.reflect.Method method = our.gui.ourTextArea.class.getMethod("getText");
                            W_LSTTEXTFIELDS.add((String)method.invoke(field.get(this)));
                        }

                        // Salvo i dati contenuti nei textfield
                        if(field.getType().toString().indexOf("TextField")>=0)
                        {
                            java.lang.reflect.Method method = our.gui.ourTextField.class.getMethod("getText");
                            W_LSTTEXTFIELDS.add((String)method.invoke(field.get(this)));
                        }

                        // Salvo i dati contenuti nelle checkbox
                        if(field.getType().toString().indexOf("CheckBox")>=0)
                        {
                            java.lang.reflect.Method method = our.gui.ourCheckBox.class.getMethod("isSelected");
                            boolean bVal = (java.lang.Boolean)method.invoke(field.get(this));
                            W_LSTTEXTFIELDS.add("" + bVal);
                        }
                         if(field.getType().toString().indexOf("Table")>=0)
                         {
                             // Ogni oggetto che inserisco è una matrice n*m contenente i dati della/e matrice/i
                             java.lang.reflect.Method method = javax.swing.JTable.class.getMethod("getRowCount");
                             int iRows = (java.lang.Integer)method.invoke(field.get(this)); // Numero di righe della matrice

                             method = javax.swing.JTable.class.getMethod("getModel");
                             javax.swing.table.DefaultTableModel tblMdl = (javax.swing.table.DefaultTableModel)method.invoke(field.get(this));

                             int iCols = tblMdl.getColumnCount();
                             String arrTmp[][] = new String[iRows][];
                             for(int x=0; x<iRows; x++)
                                 arrTmp[x] = new String[iCols]; // Alloco lo spazio per la matrice che contiene le celle di una tabella
                             for(int x=0; x<iRows; x++)
                             {
                                 for(int y=0; y<iCols; y++)
                                     arrTmp[x][y] = tblMdl.getValueAt(x, y).toString();
                             }
                             // arrTmp contiene tutte le celle di una tabella
                             W_LSTTABLES.add(arrTmp);
                         }
                    }
/*********************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per tenere una copia   *
 *********************************************************************************************************************************/                                
                            //System.out.println(fldSub[k].getName() + " : " + tmp.isExcludedFormAlter());
                }
                field.setAccessible(false);
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
    }
    
    /**
     * Questa funzione ricarica i dati contenuti nei vari campi e li
     * confronta con quelli caricati.
     * @return true se l'utente ha modificato la form, false altrimenti
     */
    public boolean isFormAlter()
    {
        boolean bRet = false;

        if(W_LSTTEXTFIELDS==null && W_LSTTABLES==null) return bRet;

        // Faccio una copia degli array contenenti i valori originali
        List lstTextFields = new ArrayList(W_LSTTEXTFIELDS);
        List lstTables     = new ArrayList(W_LSTTABLES);

        // Richiamo updateWorking per leggere i valori correnti
        updateWorking();
        
        // Verifico se ci sono differenze nei contenuti dei campi ourTextField
        for(int i=0; i<W_LSTTEXTFIELDS.size(); i++)
        {
            String txtTxt  = (String)lstTextFields.get(i);
            String txtWTxt = (String)W_LSTTEXTFIELDS.get(i);
            if(!(txtTxt.equals(txtWTxt)))
            {
                bRet = true;
                break;
            }
        }
        // Verifico se ci sono differenze nei contenuti delle griglie (se presenti)
        for(int i=0; i<W_LSTTABLES.size(); i++)
        {
            String tblTbl[][]  = (String[][])lstTables.get(i);
            String tblWTbl[][] = (String[][])W_LSTTABLES.get(i);
            // Il primo controllo che eseguo è il numero delle linee
            if( (tblTbl.length == tblWTbl.length) && (tblTbl.length>0) )
            {
                int iRowNum = tblTbl.length;
                int iColNum = tblTbl[0].length;
                for(i=0; i<iRowNum; i++)
                {
                    // Verifico cella/cella il contenuto
                    for(int y=0; y<iColNum; y++) // Verifico cella-cella
                    {
                        if(!tblTbl[i][y].equals(tblWTbl[i][y])) bRet = true;
                    }
                }
            } else {
                bRet = true;
            }
        }
/*********************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice verifica del contenuto *
 *********************************************************************************************************************************/
        // Ripristino i valori di W_LSTTEXTFIELDS e W_LSTTABLES
        W_LSTTEXTFIELDS = new ArrayList(lstTextFields);
        W_LSTTABLES     = new ArrayList(lstTables);
        return bRet;
    }

    /**
     * Cerca tra tutti gli oggetti a video, quello con il fuoco e verifica che il contenuto sia valido
     * @param bShowMessage true se si vuole visualizzare l'eventuale messaggio di errore, false altrimenti
     * @return true se il campo ha un contenuto valido, false altrimenti
     */
    private boolean checkFieldWithFocus(boolean bShowMessage)
    {
        boolean bRet = true;
        javax.swing.JComponent cmp = findComponentWithFocus();
        if(cmp==null) return bRet;
        if(cmp.getClass().toString().indexOf("TextField")>=0) {
            our.gui.ourTextField txtTmp = (our.gui.ourTextField)cmp;
            bRet = txtTmp.ISVALID(bShowMessage);
        } else if(cmp.getClass().toString().indexOf("Table")>=0) {
            our.gui.ourTable tblTmp = (our.gui.ourTable)cmp;
            bRet = tblTmp.ISVALID(bShowMessage);
        }
        return bRet;
    }
    
    
    /**
     * Questa funzione viene chiamata quando l'utente preme F9, o risponde Si
     * alla richiesta di salvataggio dei dati. Nel caso in cui 
     * si incontra un campo con valore non consentito, il fuoco viene spostato 
     * su quest'ultimo.
     * @return true se i campi sono validi, false altrimenti
     */
    private boolean checkAllFields()
    {
        // Verifico il componente che ha il fuoco
        if(!checkFieldWithFocus(true)) return false;

        boolean bRet = true;
        // Disabilito il gestore del controllo del contenuto del campo
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                //System.out.println(field.getName() + field.getType().toString());
                field.setAccessible(true);
                if(field.getType().toString().indexOf("TextField")>=0) {
                    our.gui.ourTextField txtTmp = (our.gui.ourTextField)field.get(this);
                    if(txtTmp.ISVALID(true)==false)
                    {
                        txtTmp.requestFocus();
                        bRet = false;
                        break;
                    }
                }
                if(field.getType().toString().indexOf("Table")>=0) {
                    our.gui.ourTable tblTmp = (our.gui.ourTable)field.get(this);
                    if(tblTmp.ISVALID(true)==false)
                    {
                        tblTmp.requestFocus();
                        bRet = false;
                        break;
                    }
                }
                field.setAccessible(false);
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return bRet;
    }
        
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        panelToolbar = new javax.swing.JPanel();
        butSalva = new javax.swing.JButton();
        butEsci = new javax.swing.JButton();
        butFirst = new javax.swing.JButton();
        butPrev = new javax.swing.JButton();
        butNext = new javax.swing.JButton();
        butLast = new javax.swing.JButton();
        butZoom = new javax.swing.JButton();
        butElimina = new javax.swing.JButton();
        butAzienda = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        butCalc = new javax.swing.JButton();
        butStampa = new javax.swing.JButton();
        butPrnscr = new javax.swing.JButton();
        butInfo = new javax.swing.JButton();
        butEdit = new javax.swing.JButton();
        txtID = new javax.swing.JTextField();
        panelStatus = new javax.swing.JTextField();
        panelInfo = new javax.swing.JTextField();
        panelOther = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        getContentPane().setLayout(null);

        panelToolbar.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        panelToolbar.setLayout(null);

        butSalva.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar1.gif"))); // NOI18N
        butSalva.setToolTipText("Salva record (F9)");
        butSalva.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butSalva.setEnabled(false);
        butSalva.setFocusable(false);
        butSalva.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butSalvaMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butSalvaMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butSalvaMouseExited(evt);
            }
        });
        panelToolbar.add(butSalva);
        butSalva.setBounds(10, 5, 26, 26);

        butEsci.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar2.gif"))); // NOI18N
        butEsci.setToolTipText("Esci (Esc)");
        butEsci.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butEsci.setFocusable(false);
        butEsci.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butEsciMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butEsciMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butEsciMouseExited(evt);
            }
        });
        panelToolbar.add(butEsci);
        butEsci.setBounds(38, 5, 26, 26);

        butFirst.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar3.gif"))); // NOI18N
        butFirst.setToolTipText("Vai al primo (SH+F7)");
        butFirst.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butFirst.setFocusable(false);
        butFirst.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butFirstMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butFirstMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butFirstMouseExited(evt);
            }
        });
        panelToolbar.add(butFirst);
        butFirst.setBounds(90, 5, 26, 26);

        butPrev.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar4.gif"))); // NOI18N
        butPrev.setToolTipText("Precedente (F7)");
        butPrev.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butPrev.setFocusable(false);
        butPrev.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butPrevMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butPrevMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butPrevMouseExited(evt);
            }
        });
        panelToolbar.add(butPrev);
        butPrev.setBounds(118, 5, 26, 26);

        butNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar5.gif"))); // NOI18N
        butNext.setToolTipText("Successivo (F5)");
        butNext.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butNext.setFocusable(false);
        butNext.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butNextMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butNextMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butNextMouseExited(evt);
            }
        });
        panelToolbar.add(butNext);
        butNext.setBounds(146, 5, 26, 26);

        butLast.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar6.gif"))); // NOI18N
        butLast.setToolTipText("Vai all'ultimo (SH+F5)");
        butLast.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butLast.setFocusable(false);
        butLast.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butLastMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butLastMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butLastMouseExited(evt);
            }
        });
        panelToolbar.add(butLast);
        butLast.setBounds(174, 5, 26, 26);

        butZoom.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar7.gif"))); // NOI18N
        butZoom.setToolTipText("Zoom (F2)");
        butZoom.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butZoom.setFocusable(false);
        butZoom.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butZoomMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butZoomMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butZoomMouseExited(evt);
            }
        });
        panelToolbar.add(butZoom);
        butZoom.setBounds(258, 5, 26, 26);

        butElimina.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar9.gif"))); // NOI18N
        butElimina.setToolTipText("Elimina record corrente (F8)");
        butElimina.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butElimina.setEnabled(false);
        butElimina.setFocusable(false);
        butElimina.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butEliminaMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butEliminaMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butEliminaMouseExited(evt);
            }
        });
        panelToolbar.add(butElimina);
        butElimina.setBounds(314, 5, 26, 26);

        butAzienda.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar10.gif"))); // NOI18N
        butAzienda.setToolTipText("Cambia ditta");
        butAzienda.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butAzienda.setEnabled(false);
        butAzienda.setFocusable(false);
        butAzienda.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butAziendaMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butAziendaMouseExited(evt);
            }
        });
        panelToolbar.add(butAzienda);
        butAzienda.setBounds(286, 5, 26, 26);

        jButton3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar11.gif"))); // NOI18N
        jButton3.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jButton3.setEnabled(false);
        jButton3.setFocusable(false);
        panelToolbar.add(jButton3);
        jButton3.setBounds(350, 5, 26, 26);

        butCalc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar12.gif"))); // NOI18N
        butCalc.setToolTipText("Calcolatrice");
        butCalc.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butCalc.setEnabled(false);
        butCalc.setFocusable(false);
        butCalc.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butCalcMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butCalcMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butCalcMouseExited(evt);
            }
        });
        panelToolbar.add(butCalc);
        butCalc.setBounds(378, 5, 26, 26);

        butStampa.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar13.gif"))); // NOI18N
        butStampa.setToolTipText("Stampa (F6)");
        butStampa.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butStampa.setEnabled(false);
        butStampa.setFocusable(false);
        butStampa.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butStampaMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butStampaMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butStampaMouseExited(evt);
            }
        });
        panelToolbar.add(butStampa);
        butStampa.setBounds(406, 5, 26, 26);

        butPrnscr.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar14.gif"))); // NOI18N
        butPrnscr.setToolTipText("Print Screen");
        butPrnscr.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butPrnscr.setFocusable(false);
        butPrnscr.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butPrnscrMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butPrnscrMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butPrnscrMouseExited(evt);
            }
        });
        panelToolbar.add(butPrnscr);
        butPrnscr.setBounds(434, 5, 26, 26);

        butInfo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar15.gif"))); // NOI18N
        butInfo.setToolTipText("Help");
        butInfo.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butInfo.setEnabled(false);
        butInfo.setFocusable(false);
        butInfo.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butInfoMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butInfoMouseExited(evt);
            }
        });
        panelToolbar.add(butInfo);
        butInfo.setBounds(462, 5, 26, 26);

        butEdit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/edit.gif"))); // NOI18N
        butEdit.setToolTipText("Modifica il record corrente (F3)");
        butEdit.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butEdit.setEnabled(false);
        butEdit.setFocusable(false);
        butEdit.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butEditMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butEditMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butEditMouseExited(evt);
            }
        });
        panelToolbar.add(butEdit);
        butEdit.setBounds(230, 5, 26, 26);

        txtID.setEnabled(false);
        panelToolbar.add(txtID);
        txtID.setBounds(67, 5, 20, 20);

        getContentPane().add(panelToolbar);
        panelToolbar.setBounds(0, 0, 510, 36);

        panelStatus.setEditable(false);
        panelStatus.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        panelStatus.setText("VIS ");
        panelStatus.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        panelStatus.setFocusable(false);
        getContentPane().add(panelStatus);
        panelStatus.setBounds(10, 240, 90, 21);

        panelInfo.setEditable(false);
        panelInfo.setText(" Info");
        panelInfo.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        panelInfo.setFocusable(false);
        getContentPane().add(panelInfo);
        panelInfo.setBounds(110, 240, 31, 21);

        panelOther.setEditable(false);
        panelOther.setText(" 0");
        panelOther.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        panelOther.setFocusable(false);
        getContentPane().add(panelOther);
        panelOther.setBounds(180, 240, 16, 21);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Chiede all'utente se vuole salvare il record
     * @param bShowQuestion true se vuoi visualizzare la richiesta di salvataggio,
     *                      false altrimenti
     * @return true se tutto è andato ok, false altrimenti
     */
    public boolean alter(boolean bShowQuestion) {
        int iRes = javax.swing.JOptionPane.YES_OPTION;
        if(bShowQuestion)
            iRes = our.gui.utils.MessageBox("I dati sono stati modificati: vuoi salvarli?", JOptionPane.QUESTION_MESSAGE);
        if(iRes==javax.swing.JOptionPane.YES_OPTION)
        {
            // Verifico che tutti i campi abbiano un contenuto valido
            if(checkAllFields()==false) return false;
            
            if(BEFOREWRITING(true)) // Effettuo i controlli impostati dall'utente
            {
                if(getUserMode()==MODE_MOD)
                {
                    update();
                    updateWorking();
                }
                if(getUserMode()==MODE_INS)
                {
                    insert();
                    //INSERT();
                    updateWorking();
                }            
            }
        } else {
            if(getUserMode()==MODE_INS)
            {
                removeLock();
                //DELETE();
            }
        }
        return true;
    }
    
    /**
     * Concatena tutti i valori contenuti nei campi in chiave
     * @param bIsForCheck True se devono essere concatenati anche i campi vuoti (usato solo per verificare se tutti
     *                         i campi in chiave sono stati riempiti
     *                    false altrimenti)
     * @return La stringa contenente la sequenza dei valori contenuti nei campi chiave,
     *         separati dal simbolo 'paragrafo' 
     */
    private String getKeyValsString(boolean bIsForCheck)
    {
        String strKeys = "";
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                // Lascio la prima condizione per retrocompatibilità con oggetti del tipo non our.gui puri.
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                    if( (obj!=null) && ((java.lang.Boolean)obj==true) ) { 
                        if(field.getType().toString().indexOf("TextField")>=0)
                        {
                            javax.swing.JTextField txtTmp = (javax.swing.JTextField)field.get(this);
                            if(!strKeys.isEmpty()) strKeys += "§";
                            if(bIsForCheck)
                                if(txtTmp.getText().isEmpty()) strKeys += "##";
                            strKeys += txtTmp.getText();
                        }
/************************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per la lettura del valore *
 ************************************************************************************************************************************/                        
                    }
                }
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return strKeys;
    }
    
    /**
     * Cerca nella tabella LOCKS il record identificato dall'Id in txtID.
     * In caso in cui il timestamp sia scaduto, lo annullo.
     * @return true se il record è loccato, false altrtimenti
     */
    private boolean checkLock()
    {
        boolean bIsLocked = false;
        //our.gui.dbase.models.LocksExample tmpLockEx = new our.gui.dbase.models.LocksExample();
        //tmpLockEx.createCriteria().andKeyvalsEqualTo(getKeyValsString(false)).andFormEqualTo(getTitle());
        //our.gui.dbase.models.Locks tmpLock = null;
        String strForm = getTitle();
        String strKeyvals = getKeyValsString(false);
        java.util.Date date = null;
        try {
            Statement stmt = our.gui.utils.connection.createStatement();
            String strQuery = "SELECT * FROM LOCKS WHERE ";
            strQuery += "FORM='" + strForm + "' AND ";
            strQuery += "KEYVALS='" + strKeyvals + "'";
            ResultSet rs = stmt.executeQuery(strQuery);
            while(rs.next())
            {
                date = rs.getTimestamp("TIMEST");
                break;
            }
            rs.close();
            stmt.close();
            //tmpLock = (our.gui.dbase.models.Locks)our.gui.utils.sqlMap.queryForObject("LOCKS.abatorgenerated_selectByExample", tmpLockEx);
        } catch(SQLException sqle) {
            javax.swing.JOptionPane.showMessageDialog(null, sqle.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            if(date!=null)
            {
                // Ho trovato una entry nella tabella LOCKS
                java.util.Date now = new java.util.Date();
                long lDiff = now.getTime() - date.getTime();
                if(lDiff>our.gui.utils.LOCK_TIMEOUT)
                {
                    try {
                        // Timeout scaduto, elimino l'entry
                        String strQuery = "DELETE FROM LOCKS WHERE ";
                        strQuery += "FORM='" + strForm + "' AND ";
                        strQuery += "KEYVALS='" + strKeyvals + "'";
                        our.gui.utils.connection.createStatement().executeUpdate(strQuery);
                        //our.gui.utils.sqlMap.delete("LOCKS.abatorgenerated_deleteByPrimaryKey", tmpLock);
                    } catch(SQLException sqle) {
                        javax.swing.JOptionPane.showMessageDialog(null, sqle.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
                    }
                } else {
                    bIsLocked = true;
                }
            }
            return bIsLocked;
        }
    }
    
    private void butEsciMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEsciMouseClicked
        // TODO add your handling code here:
        // Se l'utente è su un campo obbligatorio e questo è vuoto
        // ripristino la maschera senza dire nulla
        // Se è impostato il flag per la forzatura dell'uscita, esco.
       if(USER_MODE==MODE_VIS) // Tutti i campi sono disabilitati eccetto i campi chiave
        {
            boolean isEmpty = true;
            try {
                // Tramte reflection leggo tutti gli elementi JTextField appartenenti alla form e verifico che contengano qualche valore
                java.lang.reflect.Field[] flds = getClass().getDeclaredFields();
                // Ciclo tutti gl oggetti
                for(int i=0; i<flds.length; i++)
                {
                    // Identifico un singolo field
                    java.lang.reflect.Field field = getClass().getDeclaredField(flds[i].getName());
                    if(field.getType().toString().indexOf("TextField")>=0)
                    {
                        field.setAccessible(true);
                        Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                        if( (obj!=null) && ((java.lang.Boolean)obj==true) )
                        {
                            javax.swing.JTextField txtTmp = (javax.swing.JTextField)field.get(this);
                            field.setAccessible(false);
                            if( (txtTmp.getText().length()>0) && (!txtTmp.getText().equalsIgnoreCase("0")) )
                            {
                                isEmpty = false;
                                break;
                            }
                        }
                    }
                }
            } catch(Throwable t) {
                javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            }

            if(isEmpty==true)
            {
                dispose();
                return;
            }
            // Svuoto i campi
            reset();
            enableFields(false); // Chiamo questa funzione per riportare il cursore sul primo elemento in chiave
            txtID.setText("0");
            butElimina.setEnabled(false);
            butEdit.setEnabled(false);
            butAzienda.setEnabled(false);
            return;
        }
        
        boolean FORM_IS_ALTER = isFormAlter();
        
        if(FORM_IS_ALTER && alter(true)==false)
        {
            // Se ci sono campi non validati o i controlli custom dell'utente non sono passati non faccio nulla
            return;
        }
        
        removeLock();
        reset();
        enableFields(false);
        setUserMode(MODE_VIS);
        txtID.setText("0");
        butElimina.setEnabled(false);
        butEdit.setEnabled(false);
        butAzienda.setEnabled(false);
        // Ripristino le condizioni iniziali
    }//GEN-LAST:event_butEsciMouseClicked

    private void closing(javax.swing.event.InternalFrameEvent evt) {//GEN-FIRST:event_closing
        // TODO add your handling code here:
    }//GEN-LAST:event_closing

    private void butFirstMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butFirstMouseClicked
        // TODO add your handling code here:
        if(butFirst.isEnabled()) {
            //resetFields(false);
            txtID.setText("0");
            readRecord(">", "");
            GOFIRST();
            checkIfEnableEditAndDelButtons();
        }
}//GEN-LAST:event_butFirstMouseClicked

    private void butPrevMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrevMouseClicked
        // TODO add your handling code here:
        if(butPrev.isEnabled())
        {
            //resetFields(false);
            if( (txtID.getText().length()==0) || (txtID.getText().equalsIgnoreCase("0")) )
            {
                // Ho raggiunto la fine dell'archvio
                our.gui.utils.MessageBox("Hai raggiunto la fine dell'archvio!", JOptionPane.INFORMATION_MESSAGE);
            } else {
                int i = Integer.parseInt(txtID.getText()) - 1;
                if(i==0)
                {
                    // Ho raggiunto l'inizio dell'archvio
                    our.gui.utils.MessageBox("Hai raggiunto la fine dell'archvio!", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    //txtID.setText("" + i);
                    readRecord("<", "DESC");
                    checkIfEnableEditAndDelButtons();
                    GOPREV();
                }
            }
        }
    }//GEN-LAST:event_butPrevMouseClicked

    private void butNextMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butNextMouseClicked
        // TODO add your handling code here:
        if(butNext.isEnabled())
        {
            //resetFields(false);
            if(txtID.getText().length()==0)
            {
                txtID.setText("0");
            }/* else {
                int i = Integer.parseInt(txtID.getText()) + 1;
                txtID.setText("" + i); // Incremento il contenuto del campo txtID
            }*/
            readRecord(">", ""); // Leggo il record e riempio i campi con i valori prelevati dal db
            checkIfEnableEditAndDelButtons();
            GONEXT(); // Se l'utente deve fare qualcosa dopo la pressione di F5...
        }
    }//GEN-LAST:event_butNextMouseClicked


    /**
     * Effettua la lettura dal db del record
     * @param strCondizione Indica la condizione sulla quale effettuare il confronto sui campi '>=', '<', '<=' ...
     * @return true se la lettura è avvenuta, false altrimenti
     */
    private boolean readRecord(String strCondizione, String strOrd)
    {
        boolean bRet = false;

        try {
/*            our.gui.utils.sqlMap.startTransaction();
            java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();
            java.sql.Statement stmt = conn.createStatement();*/
            java.sql.Statement stmt = our.gui.utils.connection.createStatement();

            String strQuery = "SELECT * FROM " + getDB_Table() + " WHERE deleted=0 AND " + getDB_txtId_Field() + strCondizione + txtID.getText();
            //strQuery += /*" ORDER BY " + getDB_Sort_Fields() + " " + strOrd +*/ " LIMIT 1";
            strQuery += " ORDER BY id " + strOrd + " LIMIT 1";

            java.sql.ResultSet rs = stmt.executeQuery(strQuery);
            
            //our.gui.utils.sqlMap.endTransaction();

            bRet = rs.next();
            if(bRet)
            {
                setFieldsValue(rs); // Visualizzo i dati appena caricati
            } else {
                // Ho raggiunto la fine dell'archvio
                our.gui.utils.MessageBox("Hai raggiunto la fine dell'archvio!", JOptionPane.INFORMATION_MESSAGE);
            }
            rs.close();
            stmt.close();
        } catch(java.sql.SQLException e) {
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            return bRet;
        }
    }

    /**
     * Effettua la lettura dal db del record. Questa funzione viene richiamata per accedere
     * direttamente ad un record (vedi GOTO()).
     * @param strClausola Indica la clausola per la ricerca di un record
     * @return true se la lettura è avvenuta, false altrimenti
     */
    public boolean readRecord(String strClausola)
    {
        boolean bRet = false;

        try {
            /*our.gui.utils.sqlMap.startTransaction();
            java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();
            java.sql.Statement stmt = conn.createStatement();*/
            java.sql.Statement stmt = our.gui.utils.connection.createStatement();


            //String strQuery = "SELECT * FROM " + getDB_Table() + " WHERE deleted=0 AND " + strClausola;
            String strQuery = "SELECT * FROM " + getDB_Table() + " WHERE " + strClausola;
            strQuery += " LIMIT 1";

            java.sql.ResultSet rs = stmt.executeQuery(strQuery);
            //our.gui.utils.sqlMap.endTransaction();

            bRet = rs.next();
            if(bRet)
            {
                if(rs.getBoolean("deleted")==true)
                {
                    our.gui.utils.MessageBox("Il record cercato occupa una posizione riservata non accessibile. Rivolgersi all'amministratore.", JOptionPane.WARNING_MESSAGE);
                } else {
                    setFieldsValue(rs);
                }
            } // Visualizzo i dati appena caricati
        } catch(java.sql.SQLException e) {
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            return bRet;
        }
    }

    /**
     * Restituisce una lista con le coppie (chiave, valore) relativa ad ogni singolo campo.
     * Viene passata anche una coppia ('txtID', 'value') che indica il valore da mettere nel campo txtID
     * @return
     */
    /*private String[][] getKeyValList()
    {
        String strRet[][] = new String[form_db_binding.length - 1][2];

        for(int i=1; i<form_db_binding.length - 1; i++)
        {
            Object obj = form_db_binding[i][0]; // Oggetto ourTextfi - 1eld, ourCheckbox ecc ecc
            strRet[i - 1][0] = (java.lang.String)form_db_binding[i][1]; // Nome (key) del campo
            if(obj instanceof ourTextField) strRet[i - 1][1] = "'" + ((ourTextField)obj).getText().replaceAll("[']", "\"") + "'";
            if(obj instanceof javax.swing.JTextField) {
                // Verifico se si tratta di txtID
                javax.swing.JTextField txt = (javax.swing.JTextField)obj;
                if(txt.isVisible()==false && (txt.getX()==67) && (txt.getY()==5) && (txt.getWidth()==20) && (txt.getHeight()==20) )
                {
                    // E' il campo txtID
                    strRet[i - 1][0] = "txtID";
                    strRet[i - 1][1] = (java.lang.String)form_db_binding[i][1];
                }
            }
            if(obj instanceof ourCheckBox)
            {
                 ourCheckBox chkbx = (ourCheckBox)obj;
                 if(chkbx.isSelected()) strRet[i - 1][1]="'1'"; else strRet[i - 1][1]="'0'";
            }
        }
        return strRet;
    }*/
    
    /**
     * Riempio i campi con i valori appena caricati
     */
    /*private void setfieldsvalue(java.sql.ResultSet rs)
    {
        try {
            java.sql.ResultSetMetaData meta = rs.getMetaData();
            for(int i=1; i<form_db_binding.length; i++)
            {
                String strVal = "";
                Object obj = form_db_binding[i][0]; // Oggetto ourTextfield, ourCheckbox ecc ecc
                String strFldName = (java.lang.String)form_db_binding[i][1]; // Nome del campo
                // In 'meta' cerco il tipo corrispondente al nome del campo, leggo il valore
                // e lo converto in stringa
                for(int x=1; x<=meta.getColumnCount(); x++)
                {
                    String strColName = meta.getColumnName(x);
                    if(strColName.equalsIgnoreCase(strFldName))
                    {
                        // Ho trovato il campo... cerco il tipo
                        int iType = meta.getColumnType(x);

                        switch(iType) {
                            case java.sql.Types.BIT:
                            case java.sql.Types.TINYINT:
                            case java.sql.Types.INTEGER: strVal = "" + rs.getInt(strColName); break;
                            case java.sql.Types.VARCHAR: strVal = rs.getString(strColName); break;
                            default: break;
                        }

                        if(obj instanceof ourTextField) ((ourTextField)obj).setText(strVal);

                        if(obj instanceof javax.swing.JTextField) ((javax.swing.JTextField)obj).setText(strVal);

                        if(obj instanceof ourCheckBox)
                        {
                            ourCheckBox chkbx = (ourCheckBox)obj;
                            if(strVal.equalsIgnoreCase("1"))
                            {
                                chkbx.setSelected(true);
                            } else {
                                chkbx.setSelected(false);
                            }
                        }
                        break; // Una volta trovato il campo non è necessario proseguire...
                    }
                }
            }
        } catch(java.sql.SQLException e) {
            e.printStackTrace();
            System.out.println("Errore in setfieldsvalue");
        }
    }*/

    /**
     * Ritona il nome della tabella a cui la form si appoggia
     * @return
     */
    /*private String getTableName()
    {
        Object[] objGen = form_db_binding[0];
        return (java.lang.String)objGen[0];
    }*/

    /**
     * Ritorna il nome dei campi per l'ordinamento nel formato campo1, campo2...
     * @return
     */
    /*private String getSortFields()
    {
        Object[] objGen = form_db_binding[0];
        String strFlds = "";
        for(int i=1; i<objGen.length; i++) // Parto da 1 perchè il primo elemento è il nome della tabella
            strFlds += (java.lang.String)objGen[i] + ", ";
        strFlds = strFlds.substring(0, strFlds.length() - 2);
        return strFlds;
    }*/

    private void butLastMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butLastMouseClicked
        // TODO add your handling code here:
        if(butLast.isEnabled())
        {
            //resetFields(false);
            txtID.setText("0");
            readRecord(">", "DESC");
            GOLAST();
            checkIfEnableEditAndDelButtons();
        }
}//GEN-LAST:event_butLastMouseClicked


    /**
     * Sfruttando la tecnica della reflection, mi permette di venire a conoscenza dell'esistenza o meno
     * di un determinato metodo all'interno di un oggetto. L'implementazione di questa funzione, mi permette
     * di evitare la chiamata ad un metodo di un oggetto inesistente.
     * 
     * Esempio:
     * java.lang.reflect.Field field = this.getClass().getDeclaredField("mioOggetto");
     * bRet = methodExist(field.get(this).getClass().getDeclaredMethods(), "miaFunzione");
     * 
     * @param mtds Array contenente l'elenco dei metodi supportati da un determinato oggetto
     * @param strMethod Il nome del metodo da cercare
     * @return true se il metodo esiste, false altrimenti
     */
    private boolean methodExist(java.lang.reflect.Method[] mtds, String strMethod)
    {
        boolean bRet = false;

        for(int i=0; i<mtds.length; i++)
        {
            if(mtds[i].getName().indexOf(strMethod)>=0)
            {
                bRet = true;
                break;
            }
        }
        return bRet;
    }

    /**
     * Abilita i campi non in chiave e disabilita tutti gli atri se bEnable = false
     * Abilita tutti i campi eccetto quelli in chiave se bEnable = true
     * @param bEnable true siamo fuori dal keyframe, false altrimenti
     */
    public void enableFields(boolean bEnable) {
        // 17/04/2009
        // Se c'è un campo di testo che ha il fuoco, con del testo selezionato, lo deseleziono
        javax.swing.JComponent cmp = findComponentWithFocus();
        if( (cmp!=null) && (cmp.getClass().toString().indexOf("ourTextField")>=0) )
        {
            ourTextField txt = (ourTextField)cmp;
            txt.select(0, 0);
        }

        for(int x=0; x<this._KEYFIELDS.length; x++)
        {
            System.out.println(this._KEYFIELDS[x].toString());
        }

        boolean bIsFocusSet = false;
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gli oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                //System.out.println("--> " + field.getName() + field.getType().toString());
                // Lascio la prima parte del controllo per retro compatibilità
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                    if(obj!=null) 
                    {
                        boolean bIsFieldInKeyFrame = (java.lang.Boolean)obj;                     
                        java.lang.reflect.Method method = javax.swing.JComponent.class.getDeclaredMethod("setEnabled", boolean.class);
                        if(bIsFieldInKeyFrame)
                        {
                            method.invoke(field.get(this), !bEnable);
                            if( (!bIsFocusSet) && (!bEnable) )
                            {
                                obj = getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "getIsFirstOfKeyFrame");
                                if((java.lang.Boolean)obj==true)
                                {
                                    method = javax.swing.JComponent.class.getDeclaredMethod("requestFocus");
                                    method.invoke(field.get(this));
                                    bIsFocusSet = true;
                                    // 01/04/2009        Questo per evitare i problemi generati dal caso:
                                    //currentObj = obj; // I elemento fuori dal keyframe => salto del controllo
                                }                     // sull'elemento successivo.
                            }
                        } else {
                            method.invoke(field.get(this), bEnable);
                            if( (!bIsFocusSet) && (bEnable) )
                            {
                                if(field.getType().toString().indexOf("ourTextField")>=0)
                                    method = our.gui.ourTextField.class.getDeclaredMethod("isFirstFieldOutOfKeyFrame");
                                else if(field.getType().toString().indexOf("ourTextArea")>=0)
                                        method = our.gui.ourTextArea.class.getDeclaredMethod("isFirstFieldOutOfKeyFrame");
                                else if(field.getType().toString().indexOf("ourCheckBox")>=0)
                                        method = our.gui.ourCheckBox.class.getDeclaredMethod("isFirstFieldOutOfKeyFrame");
                                if((Boolean)method.invoke(field.get(this)))
                                {
                                    method = javax.swing.JComponent.class.getDeclaredMethod("requestFocus");
                                    method.invoke(field.get(this));
                                    bIsFocusSet = true;
                                }
                            }
                        }
                    }
                }
                field.setAccessible(false);
            }
            // Ciclo tutti gli elementi di tipo ZoomOn Buttons
            java.util.Iterator i = _ZOOMON_BUTTONS.iterator();
            while(i.hasNext())
            {
                ourButton but = (ourButton)i.next();
                if(but.SETTINGS.isFieldInKeyFrame()) but.setEnabled(!bEnable); else but.setEnabled(bEnable);
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            ENABLE(bEnable); // Chiamo la corrispondente funzione nella form creata dallo sviluppatore
            _ISKEYFRAMEENABLED = !bEnable;
            // 17/04/2009
        }
    }
    /* funzione originale
public void enableFields(boolean bEnable) {
        // 17/04/2009
        boolean bIsFocusSet = false;
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                //System.out.println(field.getName() + field.getType().toString());
                // Lascio la prima parte del controllo per retro compatibilità
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                    if(obj!=null)
                    {
                        boolean bIsFieldInKeyFrame = (java.lang.Boolean)obj;
                        java.lang.reflect.Method method = javax.swing.JComponent.class.getDeclaredMethod("setEnabled", boolean.class);
                        if(bIsFieldInKeyFrame)
                        {
                            method.invoke(field.get(this), !bEnable);
                            if( (!bIsFocusSet) && (!bEnable) )
                            {
                                obj = getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "getIsFirstOfKeyFrame");
                                if((java.lang.Boolean)obj==true)
                                {
                                    method = javax.swing.JComponent.class.getDeclaredMethod("requestFocus");
                                    method.invoke(field.get(this));
                                    bIsFocusSet = true;
                                    // 01/04/2009        Questo per evitare i problemi generati dal caso:
                                    //currentObj = obj; // I elemento fuori dal keyframe => salto del controllo
                                }                     // sull'elemento successivo.
                            }
                        } else {
                            method.invoke(field.get(this), bEnable);
                            if( (!bIsFocusSet) && (bEnable) )
                            {
                                obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "getIsFirstOutOfKeyFrame");
                                if((java.lang.Boolean)obj)
                                {
                                    method = javax.swing.JComponent.class.getDeclaredMethod("requestFocus");
                                    method.invoke(field.get(this));
                                    bIsFocusSet = true;
                                }
                            }
                        }
                    }
                }
                field.setAccessible(false);
            }
        } catch(Throwable t) {
            t.printStackTrace();
        } finally {
            ENABLE(bEnable); // Chiamo la corrispondente funzione nella form creata dallo sviluppatore
            _ISKEYFRAMEENABLED = !bEnable;
            // 17/04/2009
        }
    }*/


    /**
     * Funzione richiamata da serFieldsValue. Cerca nei ResultSetMetaData il valore contenuto
     * nel campo passato e ritorna il contenuto
     * @param meta MetaData del resultSet
     * @param strFieldname Nome del campo (db) del quale prelevare il dato
     * @return Il contenuto del campo
     */
    private String getDataFromResultSet(java.sql.ResultSet rs, String strFldName)
    {
        String strRet = "";
        try {
            java.sql.ResultSetMetaData meta = rs.getMetaData();
            for(int x=1; x<=meta.getColumnCount(); x++)
            {
                String strColName = meta.getColumnName(x);
                if(strColName.equalsIgnoreCase(strFldName))
                {
                    // Ho trovato il campo... cerco il tipo
                    int iType = meta.getColumnType(x);

                    switch(iType) {
                        case java.sql.Types.BIT:
                        case java.sql.Types.TINYINT:
                        case java.sql.Types.INTEGER: strRet = "" + rs.getInt(strColName); break;
                        case java.sql.Types.VARCHAR: strRet = rs.getString(strColName); break;
                        case java.sql.Types.BOOLEAN: strRet = (rs.getBoolean(strColName)==true) ? "1" : "0"; break;
                        default: break;
                    }
                    break; // Una volta trovato il campo non è necessario proseguire...
                }
            }
        } catch(java.sql.SQLException sqle) {
            javax.swing.JOptionPane.showMessageDialog(null, sqle.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return strRet;
    }

    /**
     * Imposta il tipo di cancellazione del record:
     * true: viene eliminato fisicamente con la statement DELETE
     * false: (default) viene settato a true il campo deleted
     * @param bRealDelete boolean true/false
     */
    protected void setRealDelete(boolean bRealDelete)
    {
        _bREALDELETE = bRealDelete;
    }


    private String[][] getFieldsValue()
    {
        String[][] arrRet = null;
        try {
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            arrRet = new String[flds.length + 1][]; // Valore abbastanza grande per contenre tutti gli elementi
            int iCount = 0;
            // Aggiunto il contenuto di txtID se presente
            if(txtID.getText().length()>0 && Integer.parseInt(txtID.getText())>0)
            {
                arrRet[iCount] = new String[2];
                arrRet[iCount][0] = getDB_txtId_Field();
                arrRet[iCount][1] = txtID.getText();
                iCount++;
            }
            for(int i=0; i<flds.length; i++)
            {
                // Svuoto ogni oggetto JTextField (ourTextField)
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                field.setAccessible(true);
                if(flds[i].getType().toString().indexOf("ourTextField")>=0)
                {
                    arrRet[iCount] = new String[2];
                    ourTextField tmp = (ourTextField)field.get(this);
                    arrRet[iCount][0] = tmp.getFieldOnDB();
                    arrRet[iCount++][1] = tmp.getText();
                } else if(flds[i].getType().toString().indexOf("CheckBox")>=0)
                {
                    arrRet[iCount] = new String[2];
                    our.gui.ourCheckBox tmp = (our.gui.ourCheckBox)field.get(this);
                    arrRet[iCount][0] = tmp.getFieldOnDB();
                    if(tmp.isSelected())
                        arrRet[iCount++][1] = "1";
                    else
                        arrRet[iCount++][1] = "0";
                } else if(flds[i].getType().toString().indexOf("ourTextArea")>=0) {
                    arrRet[iCount] = new String[2];
                    ourTextArea tmp = (ourTextArea)field.get(this);
                    arrRet[iCount][0] = tmp.getFieldOnDB();
                    arrRet[iCount++][1] = tmp.getText();
                }
            }
            GETFIELDSVALUE();
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        return arrRet;
    }


    private void setFieldsValue(java.sql.ResultSet rs)
    {
        try {
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            for(int i=0; i<flds.length; i++)
            {
                // Svuoto ogni oggetto JTextField (ourTextField)
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                field.setAccessible(true);
                if(flds[i].getType().toString().indexOf("ourTextField")>=0) 
                {
                    ourTextField tmp = (ourTextField)field.get(this);
                    tmp.setText(getDataFromResultSet(rs, tmp.getFieldOnDB()));
                } else if(flds[i].getType().toString().indexOf("CheckBox")>=0)
                {
                    our.gui.ourCheckBox chkBox = (our.gui.ourCheckBox)field.get(this);
                    if(getDataFromResultSet(rs, chkBox.getFieldOnDB()).startsWith("1"))
                    {
                        chkBox.setSelected(true);
                    } else {
                        chkBox.setSelected(false);
                    }
                } else if(flds[i].getType().toString().indexOf("ourTextArea")>=0) {
                    ourTextArea tmp = (ourTextArea)field.get(this);
                    tmp.setText(getDataFromResultSet(rs, tmp.getFieldOnDB()));
                }
            }
            // Setto il contenuto di txtID
            txtID.setText(getDataFromResultSet(rs, getDB_txtId_Field()));
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
/****************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per la 'pulizia'  *
 ****************************************************************************************************************************/
        //if(!bKeyFrameFieldsToo) txtID.setText(strID); else txtID.setText("0");
        // Svuoto eventuali campi di visualizzazione (a carico dell'utente)
        RESET();
        System.out.println("txtID: " + txtID.getText());
    }



    /**
     * Resetta il contenuto di tutti i campi
     * @param bKeyFrameFieldsToo true se devo svuotare il contenuto dei campi in chiave, false altrimenti
     */
    public void resetFields(boolean bKeyFrameFieldsToo) {
        String strID = txtID.getText(); // Faccio una copia del contenuto del campo hidden ID
        _KEYFLDSVALS = ""; // Svuoto la stringa contenenente i valori dei campi chiave
        try {
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            for(int i=0; i<flds.length; i++)
            {
                // Svuoto ogni oggetto JTextField (ourTextField)
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                field.setAccessible(true);
                if( (flds[i].getType().toString().indexOf("TextField")>=0) ||
                    (flds[i].getType().toString().indexOf("TextArea")>=0) ||
                    (flds[i].getType().toString().indexOf("Label")>=0) )
                {
                    Object obj = this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isFieldInKeyFrame");
                    if(!bKeyFrameFieldsToo) 
                    { // Se entro qui non devo svuotare i campi in chiave
                        if(obj!=null)
                        {
                            boolean bIsFieldInKeyFrame = (java.lang.Boolean)obj;
                            if(!bIsFieldInKeyFrame)
                            {
                                java.lang.reflect.Method method = null;
                                if(flds[i].getType().toString().indexOf("TextField")>=0)
                                {
                                    //method = javax.swing.JTextField.class.getMethod("reset", java.lang.String.class);
                                    method = our.gui.ourTextField.class.getMethod("reset");//, java.lang.String.class);
                                    if(method!=null)
                                    {
                                        method.invoke(field.get(this));
                                    } else {
                                        method = javax.swing.JTextField.class.getMethod("setText", java.lang.String.class);
                                        method.invoke(field.get(this), "");
                                    }
                                }
                                if( (flds[i].getType().toString().indexOf("ourLabel")>=0) &&
                                    ((java.lang.Boolean)this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isShow")) )
                                {
                                    method = javax.swing.JLabel.class.getMethod("setText", java.lang.String.class);
                                    if(method!=null) method.invoke(field.get(this), "");
                                }
                            }
                        }
                    } else if(obj!=null) { // obj!=null mi permette la modifica SOLO agli oggetti ourLabel, ourTextField ecc ecc
                        java.lang.reflect.Method method = null;
                        if(flds[i].getType().toString().indexOf("TextField")>=0)
                        {
                            method = our.gui.ourTextField.class.getMethod("reset");
                            if(method!=null) method.invoke(field.get(this));
                        }
                        if( (flds[i].getType().toString().indexOf("Label")>=0) &&
                            ((java.lang.Boolean)this.getCommonObjectFunction(this.getClass().getDeclaredField(field.getName()), "isShow")) )
                        {
                            method = our.gui.ourLabel.class.getMethod("setText", java.lang.String.class);
                            if(method!=null) method.invoke(field.get(this), "");
                        }
                        if(flds[i].getType().toString().indexOf("TextArea")>=0)
                        {
                            method = javax.swing.JTextArea.class.getMethod("setText", java.lang.String.class);
                            method.invoke(field.get(this), "");
                        }
                    }
                } else if(flds[i].getType().toString().indexOf("Table")>=0) // Per ogni oggetto JTable (ourTable) svuoto la griglia
                {
                    java.lang.reflect.Method method = javax.swing.JTable.class.getMethod("getModel");
                    javax.swing.table.DefaultTableModel tblMdl = (javax.swing.table.DefaultTableModel)method.invoke(field.get(this));
                    for(int x=tblMdl.getRowCount()-1; x>-1; --x)
                        tblMdl.removeRow(x);
                } else if(flds[i].getType().toString().indexOf("ButtonGroup")>=0)
                {
                    javax.swing.ButtonGroup group = (javax.swing.ButtonGroup)field.get(this);
                    group.clearSelection();
                } else if(flds[i].getType().toString().indexOf("CheckBox")>=0)
                {
                    our.gui.ourCheckBox chkBox = (our.gui.ourCheckBox)field.get(this);
                    chkBox.reset();
                }
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
/****************************************************************************************************************************
 * Nel caso in cui in chiave ci possano essere altre tipologie di controlli, bisogna aggiungere il codice per la 'pulizia'  *
 ****************************************************************************************************************************/
        if(!bKeyFrameFieldsToo) txtID.setText(strID); else txtID.setText("0");
        // Svuoto eventuali campi di visualizzazione (a carico dell'utente)
        RESET();
    }

    private void update()
    {
        String strKeyVal[][] = getFieldsValue();
        String strKeys = "", strVals = "";
        //String strTxtID = null;
        String $query = "UPDATE " + getDB_Table() + " SET ";
        for(int i=1; i<strKeyVal.length - 1; i++)
        {
            if(strKeyVal[i]==null) continue;
            $query += strKeyVal[i][0] + "='" + strKeyVal[i][1] + "', ";
        }
        $query = $query.substring(0, $query.length() - 2);
        $query += " WHERE " + strKeyVal[0][0] + "='" + strKeyVal[0][1] + "'";

        setCustomCursor(Cursor.WAIT_CURSOR);
        try {
            /*our.gui.utils.sqlMap.startTransaction();
            java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();*/
            java.sql.Statement stmt = our.gui.utils.connection.createStatement();
            stmt.executeUpdate($query);
            UPDATE();
            //our.gui.utils.sqlMap.endTransaction();
        } catch(java.sql.SQLException e) {
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            setCustomCursor(Cursor.DEFAULT_CURSOR);
        }
    }



    private void insert()
    {
        String strKeyVal[][] = getFieldsValue();
        String strKeys = "", strVals = "";
        //String strTxtID = null;
        for(int i=0; i<strKeyVal.length - 1; i++)
        {
            if(strKeyVal[i]==null) continue;
            if(strKeyVal[i][0].equals(this.getDB_txtId_Field()))
            {
                // Copio il contenuto della chiave in txtID (se le condizioni lo permettono)
                txtID.setText(strKeyVal[i][1]);
            }
            strKeys += strKeyVal[i][0] + ", ";
            strVals += "'" + strKeyVal[i][1] + "', ";
        }
        strKeys = strKeys.substring(0, strKeys.length() - 2);
        strVals = strVals.substring(0, strVals.length() - 2);

        String $query = "INSERT INTO " + getDB_Table() + "(" + strKeys;
        $query += ") VALUES (" + strVals + ")";
        
        setCustomCursor(Cursor.WAIT_CURSOR);

        try {
            /*our.gui.utils.sqlMap.startTransaction();
            java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();*/
            java.sql.Statement stmt = our.gui.utils.connection.createStatement();
            //System.out.println($query);
            stmt.execute($query);
            //our.gui.utils.sqlMap.endTransaction();
            INSERT();
        } catch(java.sql.SQLException e) {
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            setCustomCursor(Cursor.DEFAULT_CURSOR);
        }
    }
    
    private void butSalvaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butSalvaMouseClicked
        boolean bCanClose = false;
        if(!butSalva.isEnabled()) return;
        //KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        //kfm.focusNextComponent();
        // Diabilito il controolo sul contenuto dei campi
        //_OBJECTLOSTFOCUSCHECK = false;
        // Aggiorno la stringa che contiene i valori dei campi in chiave
        _KEYFLDSVALS = getKeyValsString(true);
        // Sposo il fuoco sull'elemento successivo in questo modo valido il campo
        if( (USER_MODE==MODE_INS) && checkAllFields() )
        {
            bCanClose = true;
            insert();
            //INSERT();
            // Rimuovo il lock sul record
            removeLock();
            // Disabilito i campi
            enableFields(false);
            if(!_ISZOOMONZOOM)
            {
                // Svuoto i campi
                reset();
                // Riporto l'utente in modalità visualizzazione
                setUserMode(MODE_VIS);
                // Disbilito il pusante di edit (essendo ora la scheda vuota) e delete
                butEdit.setEnabled(false);
                butElimina.setEnabled(false);
            }
        }
        
        if(USER_MODE==MODE_MOD/* && isFormAlter()*/)// && alter())
        {
            //boolean bIsAlter = isFormAlter();
            if( (isFormAlter() && alter(false) ) || (!isFormAlter()) )
            {
                // Abilito la chiusura della finestra se ZoomOnZoom
                bCanClose = true;
                // Rimuovo il lock sul record
                removeLock();
                if(!_ISZOOMONZOOM)
                {
                    // Svuoto i campi
                    reset();
                    // Disabilito i campi
                    enableFields(false);
                    // Riporto l'utente in modalità visualizzazione
                    setUserMode(MODE_VIS);
                    // Disbilito il pusante di edit (essendo ora la scheda vuota) e delete
                    butEdit.setEnabled(false);
                    butElimina.setEnabled(false);
                }
            }
            // Commenatate in data 23/03
            /*_OBJECTLOSTFOCUSCHECK = false;
            currentObj = null;*/
        }

        if(USER_MODE==MODE_VIS && _ISZOOMONZOOM) bCanClose = true;

        // Ripristino il gestore del controllo del contenuto del campo
        //_OBJECTLOSTFOCUSCHECK = true;
        //currentObj = null;
        // Se la form è chiamata da un F4, alla pressione del tasto F9 chiudo la finestra
        if( (_ISZOOMONZOOM) && (bCanClose) )//setVisible(false);
            dispose();
    }//GEN-LAST:event_butSalvaMouseClicked

    private void butEliminaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEliminaMouseClicked
        // TODO add your handling code here:
        if(!butElimina.isEnabled()) return;
        // Se l'utente non è abilitato alla rimozione di un record lo segnalo
        if(our.gui.utils.USER_ALLOW_DEL==false)
        {
            our.gui.utils.MessageBox("Utente non abilitato all'operazione richiesta!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        int iRes = our.gui.utils.MessageBox("Vuoi veramente cancellare il record corrente?", JOptionPane.QUESTION_MESSAGE);
        if (iRes==javax.swing.JOptionPane.YES_OPTION)
        {
            setLock(false);
            //DELETE();
            delete();
            removeLock();
            reset();
            butElimina.setEnabled(false);
            butEdit.setEnabled(false);
        }
    }//GEN-LAST:event_butEliminaMouseClicked

    private void delete()
    {
        String $query = "";
        if(_bREALDELETE)
        {
            $query = "DELETE FROM " + getDB_Table() + " WHERE " + getDB_txtId_Field() + "='" + txtID.getText() + "'";
        } else {
            $query = "UPDATE " + getDB_Table() + " SET deleted='1' WHERE " + getDB_txtId_Field() + "='" + txtID.getText() + "'";
        }
        
        setCustomCursor(Cursor.WAIT_CURSOR);
        try {
            /*our.gui.utils.sqlMap.startTransaction();
            java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();*/
            java.sql.Statement stmt = our.gui.utils.connection.createStatement();
            stmt.execute($query);
            DELETE();
            //our.gui.utils.sqlMap.endTransaction();
        } catch(java.sql.SQLException e) {
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            setCustomCursor(Cursor.DEFAULT_CURSOR);
        }
    }

    private void butCalcMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butCalcMouseClicked
        // TODO add your handling code here:
        if(!butCalc.isEnabled()) return;
        /*if(ourForm.appCalc==null)
        {
            appCalc = new our.gui.ourCalc(null, true);
        }
        if(appCalc.isVisible()==false)
            appCalc.setVisible(true);*/
        
    }//GEN-LAST:event_butCalcMouseClicked

    /**
     * Cerca tra tutti gli oggetti di tipo Table e TextField quello che possiede il fuoco
     * e lo restituise in forma di JComponent
     * @return Il componente che ha il fuoco
     */
    private javax.swing.JComponent findComponentWithFocus()
    {
        javax.swing.JComponent cmpRet = null;
        // Cerco l'oggetto che ha il fuoco
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                if( (field.getType().toString().indexOf("TextField")>=0) ||
                    (field.getType().toString().indexOf("Table")>=0)     ||
                    (field.getType().toString().indexOf("TextArea")>=0)     ||
                    (field.getType().toString().indexOf("CheckBox")>=0)   ) {
                    // Lo rendo accessibile
                    field.setAccessible(true);
                    java.lang.reflect.Method method = javax.swing.JComponent.class.getMethod("hasFocus");
                    boolean bHasFocus = (java.lang.Boolean)method.invoke(field.get(this));
                    if(bHasFocus)
                    {
                        cmpRet = (javax.swing.JComponent)field.get(this);
                        break;
                    }
                }
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            return cmpRet;
        }
    }

    /**
     * Funzione richiamata dai vari oggetti a video se attivati mediante evento MOUSE_CLICKED
     * @param cmpTarget Il componente cha ha generato l'evento MOUSE_CLICKED
     * @return true se il componente che possiede il fuoco è valido, false altrimenti
     */
    protected boolean clickOnComponent(javax.swing.JComponent cmpTarget)
    {
        boolean bRet = false;
        javax.swing.JComponent cmp = findComponentWithFocus();
        if(cmp.getClass().toString().indexOf("TextArea")>=0)
        {
            if(((ourTextArea)cmp).ISVALID(true))
            {
                cmpTarget.requestFocus();
                bRet = true;
            }
        }

        if(cmp.getClass().toString().indexOf("TextField")>=0)
        {
            if(((ourTextField)cmp).ISVALID(true))
            {
                cmpTarget.requestFocus();
                bRet = true;
            }
        }
        if(cmp.getClass().toString().indexOf("Table")>=0)
        {
            if(((ourTable)cmp).ISVALID(true))
            {
                cmpTarget.requestFocus();
                bRet = true;
            }
        }
        if(cmp.getClass().toString().indexOf("CheckBox")>=0)
        {
            bRet = true;
        }
        return bRet;
    }

    private void butZoomMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butZoomMouseClicked
        // TODO add your handling code here:
        if(!butZoom.isEnabled()) return;
        // Cerco l'oggetto che ha il fuoco e richiamo la funzione CALLZOOM
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                // Il primo controllo lo lascio per retro compatibilità con oggetti non our
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                    java.lang.reflect.Method method = javax.swing.JComponent.class.getMethod("hasFocus");
                    boolean bHasFocus = (java.lang.Boolean)method.invoke(field.get(this));
                    if(bHasFocus)
                    {
                         if(field.getType().toString().indexOf("TextField")>=0) {
                             our.gui.ourTextField txtTmp = (our.gui.ourTextField)field.get(this);
                             String str[] = null;
                             // Se la sorgente dell'evento MouseEvent evt è un JTextField significa che l'utente ha premuto
                             // il tasto F4: poichè ho simulato la pressione del tasto F4 con l'evento MOUSE_PRESSED sul
                             // campo txtID
                             if(evt==null || evt.getSource().getClass().getName().indexOf("JTextField")<0)
                             {
                                 str = txtTmp.SETTINGS.callZoom(txtTmp.getText(), false);
                             } else {
                                 if( txtTmp.getText().isEmpty() && (
                                     (txtTmp.getCharsInputAllowed()==our.gui.ourTextField.TYPE_CODNUM) ||
                                     (txtTmp.getCharsInputAllowed()==our.gui.ourTextField.TYPE_NUMERIC) ) )
                                 {
                                     str = txtTmp.SETTINGS.callZoomOnZoom("-999"); // Valore fittizio per identificare un valore numerico inesistente
                                 } else {
                                     str = txtTmp.SETTINGS.callZoomOnZoom(txtTmp.getText());
                                 }
                             }
                             if(str!=null) 
                             {
                                 //txtTmp.setText(str[0]);
                                 //requestFocus();
                                 txtTmp.setTextOriginal(str[1]);
                                 if( (txtTmp.getFieldShowObj()!=null) && (txtTmp.getFieldShowIdZoomCol()>=0) )
                                 {
                                     ourLabel lbl = txtTmp.getFieldShowObj();
                                     lbl.setText(txtTmp.SETTINGS.fillObj(txtTmp.getFieldShowIdZoomCol()));
                                 }
                                 //txtTmp.requestFocus();
                                 KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
                                 if(txtTmp.SETTINGS.isLastElementInKeyFrame()==false || checkLock()==true)
                                 {
                                     butEdit.setEnabled(false);
                                     butElimina.setEnabled(false);
                                 } else {
                                     if(txtTmp.SETTINGS.isLastElementInKeyFrame())
                                     {
                                         try {
                                             java.awt.Robot robot = new java.awt.Robot();

                                             robot.keyPress(KeyEvent.VK_ENTER);
                                             robot.keyRelease(KeyEvent.VK_ENTER);
                                         } catch(java.awt.AWTException e) { }                                      
                                     }
                                     butEdit.setEnabled(true);
                                     butElimina.setEnabled(true);
                                 }
                             } else {
                                 // Se l'utente preme ESC svuoto il campo
                                 txtTmp.reset();
                             }
                             requestFocus();
                             txtTmp.requestFocus();
                        }
                    }
                }
                field.setAccessible(false);
            }
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_butZoomMouseClicked

    private void butSalvaMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butSalvaMouseEntered
        // TODO add your handling code here:
        butSalva.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butSalvaMouseEntered

    private void butSalvaMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butSalvaMouseExited
        // TODO add your handling code here:
        butSalva.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butSalvaMouseExited

    private void butEsciMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEsciMouseEntered
        // TODO add your handling code here:
        butEsci.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butEsciMouseEntered

    private void butEsciMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEsciMouseExited
        // TODO add your handling code here:
        butEsci.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butEsciMouseExited

    private void butFirstMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butFirstMouseEntered
        // TODO add your handling code here:
        butFirst.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butFirstMouseEntered

    private void butFirstMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butFirstMouseExited
        // TODO add your handling code here:
        butFirst.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butFirstMouseExited

    private void butPrevMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrevMouseEntered
        // TODO add your handling code here:
        butPrev.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butPrevMouseEntered

    private void butPrevMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrevMouseExited
        // TODO add your handling code here:
        butPrev.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butPrevMouseExited

    private void butNextMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butNextMouseEntered
        // TODO add your handling code here:
        butNext.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butNextMouseEntered

    private void butNextMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butNextMouseExited
        // TODO add your handling code here:
        butNext.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butNextMouseExited

    private void butLastMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butLastMouseEntered
        // TODO add your handling code here:
        butLast.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butLastMouseEntered

    private void butLastMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butLastMouseExited
        // TODO add your handling code here:
        //butLast.setBorder(BUT_BORDER_EXITING);
        butLast.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
    }//GEN-LAST:event_butLastMouseExited

    private void butZoomMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butZoomMouseEntered
        // TODO add your handling code here:
        butZoom.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butZoomMouseEntered

    private void butZoomMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butZoomMouseExited
        // TODO add your handling code here:
        butZoom.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butZoomMouseExited

    private void butAziendaMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butAziendaMouseEntered
        // TODO add your handling code here:
        butAzienda.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butAziendaMouseEntered

    private void butAziendaMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butAziendaMouseExited
        // TODO add your handling code here:
        butAzienda.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butAziendaMouseExited

    private void butEliminaMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEliminaMouseEntered
        // TODO add your handling code here:
        butElimina.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butEliminaMouseEntered

    private void butEliminaMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEliminaMouseExited
        // TODO add your handling code here:
        butElimina.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butEliminaMouseExited

    private void butCalcMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butCalcMouseEntered
        // TODO add your handling code here:
        butCalc.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butCalcMouseEntered

    private void butCalcMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butCalcMouseExited
        // TODO add your handling code here:
        butCalc.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butCalcMouseExited

    private void butStampaMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butStampaMouseEntered
        // TODO add your handling code here:
        butStampa.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butStampaMouseEntered

    private void butStampaMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butStampaMouseExited
        // TODO add your handling code here:
        butStampa.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butStampaMouseExited

    private void butPrnscrMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrnscrMouseEntered
        // TODO add your handling code here:
        butPrnscr.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butPrnscrMouseEntered

    private void butPrnscrMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrnscrMouseExited
        // TODO add your handling code here:
        butPrnscr.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butPrnscrMouseExited

    private void butInfoMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butInfoMouseEntered
        // TODO add your handling code here:
        butInfo.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butInfoMouseEntered

    private void butInfoMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butInfoMouseExited
        // TODO add your handling code here:
        butInfo.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butInfoMouseExited

    private void butEditMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEditMouseEntered
        // TODO add your handling code here:
        butEdit.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butEditMouseEntered

    private void butEditMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEditMouseExited
        // TODO add your handling code here:
        butEdit.setBorder(BUT_BORDER_EXITING);
    }//GEN-LAST:event_butEditMouseExited

    private void butEditMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEditMouseClicked
        if(our.gui.utils.USER_ALLOW_EDIT==false)
        {
            // Se l'utente non è abilitato alla modifica di un record lo segnalo
            our.gui.utils.MessageBox("Utente non abilitato all'operazione richiesta!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if(butEdit.isEnabled())
        {
            if(allKeyFieldsFill()==false)
            {
                // Se i campi del keyframe non contengono valori, inibisco la modifica del record
                our.gui.utils.MessageBox("Tutti i campi in chiave devono essere compilati!", JOptionPane.WARNING_MESSAGE);
                return;
            }

            if(setLock(false)==false)
            {
                butEdit.setEnabled(false);
                return;
            }
            updateWorking(); // Aggiorno le variabili di locking
            enableFields(true);
            setUserMode(MODE_MOD);
            // Avvio il timer
            startTimer();
        }
    }//GEN-LAST:event_butEditMouseClicked

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        // TODO add your handling code here:
        //our.gui.ourForm.KEY_PRESSED = java.awt.event.KeyEvent.VK_ESCAPE;
//        _FOCUS_LOSER = new Object(); // Necessito di questo assegnamento altrimenti il gioco del fuoco impazzisce
        butEsciMouseClicked(null);
    }//GEN-LAST:event_formWindowClosing

    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        // TODO add your handling code here:
        // Se l'utente non ha impostato il nome del DB
        if(getDB_Table().length()==0 || getDB_txtId_Field().length()==0)
        {
            System.out.println("***********************************************");
            System.out.println("*                                             *");
            System.out.println("* ERRORE: Non è stato impostato il nome della *");
            System.out.println("*         tabella del database associata o il *");
            System.out.println("*         campo per il textfield txtID.       *");
            System.out.println("*                                             *");
            System.out.println("***********************************************\n\n");
            System.exit(1);
        }

        // Ciclo ogni oggetto a video e gli comunico il frame
        try {
            // Tramte reflection leggo tutti gli elementi appartenenti alla form
            java.lang.reflect.Field[] flds = this.getClass().getDeclaredFields();
            // Ciclo tutti gl oggetti
            for(int i=0; i<flds.length; i++)
            {
                // Identifico un singolo field
                java.lang.reflect.Field field = this.getClass().getDeclaredField(flds[i].getName());
                // Lo rendo accessibile
                field.setAccessible(true);
                // Il primo controllo lo lascio per retro compatibilità con oggetti non our
                if( (field.getType().toString().indexOf("javax.swing")>=0) || (field.getType().toString().indexOf("our.gui")>=0) )
                {
                     if(field.getType().toString().indexOf("ourPanel")>=0)
                     {
                         our.gui.ourPanel pnlTmp = (our.gui.ourPanel)field.get(this);
                         if(pnlTmp.isKeyFrame())
                         {
                            // Carico l'array che contiene gli oggetti che sono nel keyframe
                            _KEYFIELDS = pnlTmp.getFieldsInKeyFrame();
                            // Nei campi che sono nel keyframe mostro l'asterisco
                            //if(pnlTmp.isKeyFrame()) pnlTmp.showAsterisks();
                            pnlTmp.showAsterisks();
                         }
                     }


                     if(field.getType().toString().indexOf("TextField")>=0) {
                         our.gui.ourTextField txtTmp = (our.gui.ourTextField)field.get(this);
                         // Ad ogni oggetto comunico un riferimento al frame contenitor ourFrame
                         txtTmp.SETTINGS.setOurForm(this);
                         if(txtTmp.getZoomOnClass()!=null && txtTmp.getZoomOnClass().length()>0)
                             txtTmp.SETTINGS.zoomOn(txtTmp.getParent(), txtTmp, txtTmp.getZoomOnClass());
                         //if(txtTmp.SETTINGS.isZoom()) addZoomOnButton(txtTmp.SETTINGS.getZoomButtonObj());
                         txtTmp.SETTINGS.setHelpMsg(txtTmp.getHelpMsg());
                         if(txtTmp.getZoomOnClass()!=null && txtTmp.getText().length()>0)
                         {
                             // Se è definito il campo zoomOnClass imposto la proprietà
                             txtTmp.SETTINGS.zoomOn(txtTmp.getParent(), txtTmp, txtTmp.getZoomOnClass());
                         }
                         if(txtTmp.isIsZoomOnZoomEnabled())
                         {
                             txtTmp.SETTINGS.setZoomOnZoom(true);
                         }
                         if(txtTmp.isWithStar())
                         {
                             txtTmp.showAsterisk();
                         }
                     }
                     if(field.getType().toString().indexOf("Table")>=0) {
                         our.gui.ourTable txtTmp = (our.gui.ourTable)field.get(this);
                         // Ad ogni oggetto comunico un riferimento al frame contenitor ourFrame
                         txtTmp.SETTINGS.setOurForm(this);
                     }
                     if(field.getType().toString().indexOf("CheckBox")>=0) {
                         our.gui.ourCheckBox txtTmp = (our.gui.ourCheckBox)field.get(this);
                         txtTmp.init(); // Aggiunge l'etichetta
                         txtTmp.SETTINGS.setHelpMsg(txtTmp.getHelpMsg());
                         // Ad ogni oggetto comunico un riferimento al frame contenitor ourFrame
                         txtTmp.SETTINGS.setOurForm(this);
                     }
                }
                field.setAccessible(false);
            }
            // Abilito i campi appartenenti al keyframe
            enableFields(false);
        } catch(Throwable t) {
            javax.swing.JOptionPane.showMessageDialog(null, t.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            // Se la finestra corrente è uno zoom on zoom
            // Verifico lo stato del lock e quindi abilito o meno i pulsanti di edit/delete ecc.ecc.
            if(_ISZOOMONZOOM==true)
            {
                if(_HM_GOTO!=null)
                {
                    String str = "";
                    // Carico il record
                    str += ((ourTextField)_KEYFIELDS[0]).getFieldOnDB() + "='" + (String)_HM_GOTO[0] + "'";
                    if(readRecord(str)==false)
                    {
                        // E' stato premuto F4 con un valore non presente in archivio...
                        ((ourTextField)_KEYFIELDS[0]).setText((String)_HM_GOTO[0]);
                        try {
                            java.awt.Robot robot = new java.awt.Robot();
                            robot.keyPress(KeyEvent.VK_ENTER);
                            robot.keyRelease(KeyEvent.VK_ENTER);
                        } catch(java.awt.AWTException e) { }
                    }
                    _HM_GOTO = null;
                }
                // Se il record corrente non è loccato e ci sono dei campi in chiave ailitio i tasti edit e delete
                if( (checkLock()==false) && getKeyValsString(true).replaceAll("[#]", "").length()>0)
                {
                    butEdit.setEnabled(true);
                    butElimina.setEnabled(true);
                }
            }
        }
/*        KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        focusManager.addVetoableChangeListener("permanentFocusOwner", new java.beans.VetoableChangeListener() {
            public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
                if(_FORCEAVOIDFOCUSMANAGE) return;
                if(!_MANAGEFOCUS) return;
                if(evt.getOldValue()==null) return;
                if(_FOCUS_LOSER!=null)
                {
                    _FOCUS_LOSER = null;
                    return;
                }
                if (("permanentFocusOwner".equals(evt.getPropertyName())) && ((evt.getOldValue()) instanceof our.gui.ourTextField)) {
                    _FOCUS_LOSER = evt.getOldValue();
                    our.gui.ourTextField txtF = (ourTextField) evt.getOldValue();
                    _MANAGEFOCUS = false;
                    if(!(_ISLASTFIELDVALID=txtF.ISVALID(true)))
                    {
                        txtF.requestFocusInWindow();
                    } else {
                        _FOCUS_LOSER = null;
                    }
                    _MANAGEFOCUS = true;
                }
            }
        });
        if(_ISZOOMONZOOM) _MANAGEFOCUS = false;*/
    }//GEN-LAST:event_formWindowOpened

    private void butStampaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butStampaMouseClicked
        // TODO add your handling code here:

        javax.swing.JComponent cmpWithFocus = findComponentWithFocus();
        String strPrnForm = _PRINTFORMNAME;

        our.gui.ourPrint formPrint;
        Class printDefinition;
        Class[] ArgsClass = new Class[] { java.awt.Frame.class, boolean.class };
        Object[] ArgsVals = new Object[] { new java.awt.Frame(), new Boolean(true) };
        java.lang.reflect.Constructor ArgsConstructor;
        try {
            printDefinition = Class.forName(strPrnForm);
            ArgsConstructor = printDefinition.getConstructor(ArgsClass);
            formPrint = (our.gui.ourPrint)our.gui.commonObjectClass.createObject(ArgsConstructor, ArgsVals);
            formPrint.setVisible(true);
        } catch (ClassNotFoundException e) {
        } catch (NoSuchMethodException e) {
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(),
                                                      "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
        } finally {
            cmpWithFocus.requestFocus();
        }
    }//GEN-LAST:event_butStampaMouseClicked

    private void butPrnscrMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrnscrMouseClicked
        try {
            String fileName = javax.swing.JOptionPane.showInputDialog(null, "Nome del file : ", "Screen Capture", 1);
            if(fileName==null || fileName.length()==0) throw new Exception("User abort!");
            fileName = System.getProperty("user.home") + System.getProperty("file.separator") + fileName + ".gif";
            java.awt.Robot robot = new java.awt.Robot();
            java.awt.image.BufferedImage image = robot.createScreenCapture(new java.awt.Rectangle(
            java.awt.Toolkit.getDefaultToolkit().getScreenSize()));
            javax.imageio.ImageIO.write(image, "gif", new java.io.File(fileName));
            javax.swing.JOptionPane.showMessageDialog(null, "Cattura dello schermo completata in \n" + fileName,
                "Screen Capture", 1);
        } catch(Exception e) {} finally {
        }
    }//GEN-LAST:event_butPrnscrMouseClicked

    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    protected javax.swing.JButton butAzienda;
    protected javax.swing.JButton butCalc;
    protected javax.swing.JButton butEdit;
    protected javax.swing.JButton butElimina;
    protected javax.swing.JButton butEsci;
    protected javax.swing.JButton butFirst;
    protected javax.swing.JButton butInfo;
    protected javax.swing.JButton butLast;
    protected javax.swing.JButton butNext;
    protected javax.swing.JButton butPrev;
    protected javax.swing.JButton butPrnscr;
    protected javax.swing.JButton butSalva;
    protected javax.swing.JButton butStampa;
    protected javax.swing.JButton butZoom;
    protected javax.swing.JButton jButton3;
    public static javax.swing.JTextField panelInfo;
    private javax.swing.JTextField panelOther;
    private javax.swing.JTextField panelStatus;
    private javax.swing.JPanel panelToolbar;
    protected javax.swing.JTextField txtID;
    // End of variables declaration//GEN-END:variables


//    private Object currentObj = null;
    /**
     * Funzione richiamata dagli oggetti appartenenti alla form quando perdono il fuoco
     * @param obj L'oggetto che ha perso il fuoco
     * @return true se l'oggetto ha un contenuto valido, false altrimenti
     */
/*    public synchronized boolean ObjectLostFocus(Object obj)
    {
        boolean bRet = true;

        // Questo controllo serve per quando l'utente preme ESC ed evita l'ulteriore controllo
        if(_ONRESET)
        {
            _ONRESET = false;
            return false;
        }

        if(_OBJECTLOSTFOCUSCHECK)
        {
            if(currentObj==null)
                currentObj = obj;
            if(currentObj!=obj)
            {
                //System.out.println("Sono stato chiamato da un altro oggetto!");
                _OBJECTLOSTFOCUSCHECK = true;
                currentObj = null;
                return false;
            }
            _OBJECTLOSTFOCUSCHECK = false;
            // 15/04/2009
            our.gui.ourTextField.AVOID_CHECK = true;
            if(obj instanceof our.gui.ourTextField)
            {
                bRet = ((our.gui.ourTextField)obj).ISVALID(true);
            }
            if(bRet==false) // Il contenuto non è valido
            {
                _ONRESET= true; // Questo settaggio serve per Windows
                javax.swing.JComponent cmp = (javax.swing.JComponent)obj;
                cmp.requestFocus();
            } else {
                // 02/04/09
                currentObj = null;
            }
            // 15/04/2009
            our.gui.ourTextField.AVOID_CHECK = false;
            _OBJECTLOSTFOCUSCHECK = true;
        } else {
            return false; // Ritorno false per impedire che altre parti di codice vengano eseguite
        }
        return bRet;
    }*/
}
